package com.sc.nft.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.sc.nft.dao.*;
import com.sc.nft.dto.SaasTaskAddDTO;
import com.sc.nft.dto.UserEcologyHatchRecordsDao;
import com.sc.nft.entity.*;
import com.sc.nft.entity.dto.*;
import com.sc.nft.entity.vo.*;
import com.sc.nft.enums.*;
import com.sc.nft.enums.task.ActivityTypeEnum;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.service.*;
import com.sc.nft.sup.PageRequest;
import com.sc.nft.util.TraceContext;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 任务基础表(SaasTask)表服务实现类
 *
 * @author 王伟成
 * @since 2024-01-11 15:07:57
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class SaasTaskServiceImpl implements SaasTaskService {

    private final SaasTaskDao saasTaskDao;

    private final SaasTaskMeetConditionsOptionDao saasTaskMeetConditionsOptionDao;

    private final SaasTaskMeetConditionsDao saasTaskMeetConditionsDao;

    private final UserCreatorInfoDao userCreatorInfoDao;

    private final DigitalCollectionDao digitalCollectionDao;

    private final MallProductDao mallProductDao;

    private final UserRelevanceDao userRelevanceDao;

    private final SaasUserTaskDao saasUserTaskDao;

    private final UserCollectionDao userCollectionDao;

    private final SaasTaskAwardDao saasTaskAwardDao;

    private final SaasTaskAwardDetailsDao saasTaskAwardDetailsDao;

    private final EquityPropsService equityPropsService;

    private final UserEquityPropsService userEquityPropsService;

    private final UserInfoDao userInfoDao;

    private final UserHfExtDao userHfExtDao;

    private final LlUserExtDao llUserExtDao;

    private final Redisson redisson;

    private final MallOrderDao mallOrderDao;

    private final SaasTaskUserRecordDao saasTaskUserRecordDao;

    private final UserHnaExtDao userHnaExtDao;

    private final SaasTaskStageConditionsDao saasTaskStageConditionsDao;

    private final SaasTaskTemplateDao saasTaskTemplateDao;

    private final SaasTaskMeetConditionsLocationDao saasTaskMeetConditionsLocationDao;

    private final OrderService orderService;

    private final SecondOrderService secondOrderService;

    private final RoughStoneOrderService roughStoneOrderService;

    private final SecondEquityPropsOrderService equityPropsOrderService;

    private final SecondCollectionConfigService secondCollectionConfigService;

    private final RedisTemplate redisTemplate;

    private final UserAssetsService userAssetsService;
    private final OrderDao orderDao;
    private final MallOrderProductDao mallOrderProductDao;
    private final SaasExcludeDao saasExcludeDao;
    private final UserEcologyHatchRecordsDao userEcologyHatchRecordsDao;


    @Override
    public void startOrEnd(SaasTaskStartOrEndDTO saasTaskStartOrEndDTO) {
        SaasTask saasTask = saasTaskDao.getById(saasTaskStartOrEndDTO.getId());
        if (BeanUtil.isEmpty(saasTask)) {
            throw new GlobalRunTimeException("任务不存在");
        }
        if (saasTask.getTaskConfiguration() != SaasTaskConfigurationEnum.APPROVED) {
            throw new GlobalRunTimeException("任务需要审核通过才可以启动或关闭");
        }
        SaasTaskMeetConditions saasTaskMeetConditions = saasTaskMeetConditionsDao.getByTaskId(saasTaskStartOrEndDTO.getId());
        String key = StrUtil.format("{}:{}", RedisKeyEnum.SAAS_TASK_TYPE_EXIST.getKey(), saasTaskMeetConditions.getTaskType().name());
        redisTemplate.delete(key);
        saasTask.setTaskStatus(saasTaskStartOrEndDTO.getTaskStatus());
        saasTaskDao.updateTaskStatus(saasTaskStartOrEndDTO);
    }

    @Override
    public Map taskType() {
        List<SaasTaskTemplate> isStart = saasTaskTemplateDao.getIsStart();
        Map map = new HashMap();
        for (SaasTaskTemplate saasTaskTemplate : isStart) {
            map.put(saasTaskTemplate.getTaskType(), saasTaskTemplate.getTaskType().getDesc());
        }
        return map;
    }

    @Override
    public IPage<SaasTaskBasicsVO> pageBasics(SaasTaskBasicsDTO saasTaskBasicsDTO) {
        return saasTaskDao.pageBasics(saasTaskBasicsDTO);
    }

    @Override
    public SaasTaskDetailsVO getByIdDetails(Long id) {
        SaasTask saasTask = saasTaskDao.getById(id);
        if (BeanUtil.isEmpty(saasTask)) {
            throw new GlobalRunTimeException("任务不存在");
        }
        // 需要返回的数据实体
        SaasTaskDetailsVO saasTaskVO = BeanUtil.copyProperties(saasTask, SaasTaskDetailsVO.class);

        // 获取任务基础条件
        SaasTaskMeetConditions saasTaskMeetConditions = saasTaskMeetConditionsDao.getByTaskId(id);

        List<SaasTaskMeetConditionsLocation> saasTaskMeetConditionsLocations = saasTaskMeetConditionsLocationDao.getByMeetConditionsAndSaasTaskId(saasTaskMeetConditions.getId(), id);

        // 任务生效位置
        if (CollUtil.isNotEmpty(saasTaskMeetConditionsLocations)) {
            saasTaskVO.setSaasTaskMeetConditionsLocation(BeanUtil.copyToList(saasTaskMeetConditionsLocations, SaasTaskMeetConditionsLocationVO.class));
        }


        // 组装任务详细条件
        SaasTaskDetailsConditionVO saasTaskDetailsConditionVO = BeanUtil.copyProperties(saasTaskMeetConditions, SaasTaskDetailsConditionVO.class);

        // 任务需要持有的藏品or商品的要求
        taskAskFor(saasTaskDetailsConditionVO, saasTask, saasTaskMeetConditions);

        // 赋值任务条件字段
        saasTaskVO.setSaasTaskDetailsConditionVO(saasTaskDetailsConditionVO);


        // 根据不同的任务类型获取不同的任务详情.
        // 时间 2024-03-08 修改为ALL,全部可以看到.不在返回dao相关信息
//        if (saasTask.getTaskParticipator() == SaasTaskParticipatorEnum.ALL) {
//            // 如果是dao的话,则给saasTaskDetailsCreatorVO
//            UserCreatorInfo userDao = userCreatorInfoDao.getById(saasTask.getDaoId());
//            if (BeanUtil.isEmpty(userDao)) {
//                throw new GlobalRunTimeException("主理人不存在");
//            }
//            SaasTaskDetailsCreatorVO saasTaskDetailsCreatorVO = new SaasTaskDetailsCreatorVO();
//            saasTaskDetailsCreatorVO.setId(userDao.getId());
//            saasTaskDetailsCreatorVO.setDaoName(userDao.getDaoName());
//            saasTaskVO.setSaasTaskDetailsCreatorVO(saasTaskDetailsCreatorVO);
//        }

        if (saasTask.getTaskParticipator() == SaasTaskParticipatorEnum.HOLD_COLLECTION) {
            // 获取条件关联表数据
            List<SaasTaskMeetConditionsOption> saasTaskMeetConditionsOptions = saasTaskMeetConditionsOptionDao.getByTaskId(saasTask.getId(), null, 1);
            List<Long> collectionIds = saasTaskMeetConditionsOptions.stream().map(SaasTaskMeetConditionsOption::getConditionId).collect(Collectors.toList());
            if (CollUtil.isEmpty(collectionIds)) {
                throw new GlobalRunTimeException("任务条件数据不存在");
            }
            // 如果是持有藏品的话,则给saasTaskDetailsCollections
            List<SaasTaskDetailsCollectionVO> collectionSimplenessByIds = digitalCollectionDao.getCollectionSimplenessByIds(collectionIds);
            if (CollUtil.isNotEmpty(collectionSimplenessByIds)) {
                saasTaskVO.setSaasTaskDetailsCollections(collectionSimplenessByIds);
            } else {
                throw new GlobalRunTimeException("获取藏品数据失败");
            }
        }
        return saasTaskVO;
    }

    @Override
    public IPage<SaasTaskWebPageVO> saasTaskWebPage(SaasTaskWebPageDTO saasTaskWebPageDTO, UserInfo user) {
        // 根据daoId获取该用户是否在他下,如果不在的话,sql中就不需要关联,直接获取这个用户的藏品持符合哪些任务
        UserCreatorInfo userCreatorInfo = userCreatorInfoDao.getById(saasTaskWebPageDTO.getDaoId());
        if (BeanUtil.isEmpty(userCreatorInfo)) {
            throw new GlobalRunTimeException("该dao不存在");
        }
        // 查询这个用户是否是这个dao主理人网体下的用户
        UserRelevance subordinate = userRelevanceDao.subordinate(userCreatorInfo.getUserId(), user.getId());
        // 这个标识位是用来判定是否需要查询dao的任务
        Boolean dao = Boolean.FALSE;
        // 主理人自己也能看到网体任务
        if (user.getId().equals(userCreatorInfo.getUserId())) {
            dao = Boolean.TRUE;
        }
        if (BeanUtil.isNotEmpty(subordinate)) {
            dao = Boolean.TRUE;
        }
        return saasTaskDao.saasTaskWebPage(saasTaskWebPageDTO, user.getId(), dao);
    }

    @Override
    public SaasTaskWebDetailsVO saasTaskById(Long id, UserInfo user) {
        SaasTaskWebDetailsVO saasTaskWebDetailsVO = new SaasTaskWebDetailsVO();
        SaasTask saasTask = saasTaskDao.getById(id);
        // 处理基础数据  一个是基础表数据,一个是该任务用户目前完成了几次
        saasTaskWebDetailsVO.basics(saasTask, saasUserTaskDao.countByTaskId(id, user.getId()));

        SaasTaskMeetConditions saasTaskMeetConditions = saasTaskMeetConditionsDao.getByTaskId(id);
        SaasUserTask saasUserTask = saasUserTaskDao.getBySaasTask(id, user.getId());
        // 模板
        saasTaskWebDetailsVO.userTemplateTask(saasTaskMeetConditions, saasUserTask);
        // 完成任务模板
        saasTaskWebDetailsVO.meetConditions(saasTaskMeetConditionsDao.getByTaskId(id));

        // 根据任务参与者进行任务条件判定.如果这个任务是持有指定藏品,才进行查询
        if (saasTaskWebDetailsVO.getTaskParticipator() == SaasTaskParticipatorEnum.HOLD_COLLECTION) {
            // 获取持有条件获取藏品.
            saasTaskWebDetailsVO.setTaskConditions(userCollectionDao.saasTaskCondition(id, user.getId()));
        }

        // 获取任务完成模板所需要购买的藏品或者商品,根据不同的标识.进行判定
        if (saasTaskWebDetailsVO.getSaasTaskMeetConditionsWeb().getStatus().equals(2)) {
            // 获取nft藏品
            List<SaasTaskMeetConditionsOption> saasTaskMeetConditionsOptions = saasTaskMeetConditionsOptionDao.getByTaskId(id, saasTaskWebDetailsVO.getSaasTaskMeetConditionsWeb().getId(), 2);
            // 根据id,获取藏品数据
            List<Long> conditionIds = saasTaskMeetConditionsOptions.stream().map(SaasTaskMeetConditionsOption::getConditionId).collect(Collectors.toList());
            saasTaskWebDetailsVO.setTemplateOverlength(conditionIds.size() > 3);
            if (saasTaskMeetConditionsOptions.size() > 3) {
                // 只获取conditionIds字段的前面3个.
                conditionIds = conditionIds.subList(0, 3);
            }
            List<SaasTaskDetailsCollectionVO> collectionSimplenessByIds = digitalCollectionDao.getCollectionSimplenessByIds(conditionIds);
            saasTaskWebDetailsVO.saasTaskBuys(collectionSimplenessByIds);
        }
        if (saasTaskWebDetailsVO.getSaasTaskMeetConditionsWeb().getStatus().equals(3)) {
            // 获取商城藏品
            List<SaasTaskMeetConditionsOption> saasTaskMeetConditionsOptions = saasTaskMeetConditionsOptionDao.getByTaskId(id, saasTaskWebDetailsVO.getSaasTaskMeetConditionsWeb().getId(), 3);
            // 根据id,获取商品
            List<Long> conditionIds = saasTaskMeetConditionsOptions.stream().map(SaasTaskMeetConditionsOption::getConditionId).collect(Collectors.toList());
            saasTaskWebDetailsVO.setTemplateOverlength(conditionIds.size() > 3);
            if (saasTaskMeetConditionsOptions.size() > 3) {
                // 只获取conditionIds字段的前面3个.
                conditionIds = conditionIds.subList(0, 3);
            }
            List<SaasTaskDetailsCollectionVO> mallProductSimplenessByIds = mallProductDao.getMallProductSimplenessByIds(conditionIds);
            saasTaskWebDetailsVO.saasTaskBuys(mallProductSimplenessByIds);
        }
        // 这里要根据当前的任务剩余量,去获取他的奖励

        // 已完成任务数量
        Integer offTheStocks = saasTask.getTaskTotalSum() - saasTask.getTaskResidueSum();
        // 获取上限和下限在offTheStocks之间的奖励
        SaasTaskStageConditions saasTaskStageConditions = saasTaskStageConditionsDao.upAndDownSection(saasTask.getId(), offTheStocks);
        saasTaskWebDetailsVO.setSaasTaskStageConditions(saasTaskStageConditions);
        // 如果对象为空的话,会导致他下面使用的时候拿不到数据.报null异常,加上这个会处理掉这个问题.
        // 任务奖励基础数据
        List<SaasTaskAwardVO> byTaskIdLeftDig = saasTaskAwardDao.getByTaskIdLeftDig(id, BeanUtil.isNotEmpty(saasTaskStageConditions)?saasTaskStageConditions.getId():null);
        // 根据任务的基础奖励数据，获取任务真实奖励
        byTaskIdLeftDig.forEach(saasTaskAwardVO -> {
            List<SaasTaskAwardDetailsVO> byTaskIdLeftEquity = saasTaskAwardDetailsDao.getByTaskIdLeftEquity(id,saasTaskAwardVO.getId(), saasTaskAwardVO.getCollectionId());
            byTaskIdLeftEquity.forEach(saasTaskAwardDetailsVO -> {
                if (saasTaskAwardDetailsVO.getBoxEquityType().equals(BoxEquityTypeEnum.POINTS)) {
                    saasTaskAwardDetailsVO.setDescribe("星球碎片");
                }
            });
            saasTaskAwardVO.setSaasTaskAwardDetails(byTaskIdLeftEquity);
        });
        saasTaskWebDetailsVO.setSaasTaskAwards(byTaskIdLeftDig);
        // 调用方法,获取用户基础数据的排列id.获取所有的藏品,让后把用户的数据查出来.如果没有的话,则查找优先级最低的那个.如果有的话,根据藏品的id进行匹配查询出他的优先级
        List<Long> collectionIds = saasTaskWebDetailsVO.byTaskIdLeftDigCollectionId();
        // 根据上面的id，获取用户所有的藏品
        List<UserCollection> byCollectionIdAndUserId = userCollectionDao.getByCollectionIdAndUserId(collectionIds, user.getId());
        saasTaskWebDetailsVO.rewardRanking(byCollectionIdAndUserId);
        return saasTaskWebDetailsVO;
    }

    @Override
    public IPage<SaasUserTaskParticipatingTaskVO> userParticipatingTask(SaasUserTaskParticipatingTaskDTO saasUserTaskParticipatingTaskDTO, UserInfo user) {
        if(ObjectUtil.isNull(saasUserTaskParticipatingTaskDTO.getTaskType())){
            saasUserTaskParticipatingTaskDTO.setTaskType(SaasTaskTypePlaceEnum.DAO);
        }
        return saasTaskDao.userParticipatingTask(saasUserTaskParticipatingTaskDTO, user);
    }

    @Override
    public IPage<SaasUserWaitingToBeClaimedTaskVO> userWaitingToBeClaimedTask(SaasUserWaitingToBeClaimedTaskDTO saasUserTaskParticipatingTaskDTO, UserInfo user) {
        return saasUserTaskDao.userWaitingToBeClaimedTask(saasUserTaskParticipatingTaskDTO, user);
    }

    @Override
    public List<SaasUserTaskIdGainAwardVO> getByUserTaskIdGainAward(Long id) {
        // id为空的情况下意味着他没有奖励
        if (BeanUtil.isEmpty(id)) {
            return new ArrayList<>();
        }
        // 获取这个任务的id和他的奖励的id.去和奖励匹配.
        SaasUserTask saasUserTask = saasUserTaskDao.getById(id);
        return saasTaskAwardDetailsDao.getByUserTaskIdGainAward(saasUserTask.getSaasTaskId(), saasUserTask.getTaskAwardId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void receiveAward(Long id, UserInfo user) {
        // 任务奖励永远都可以领取,和产品口头确认过.这一行马上就记录下来了.
        // 获取用户任务,判定用户任务的状态.如果是已经领取的话,则抛异常
        SaasUserTask saasUserTask = saasUserTaskDao.getByIdAndUserId(id, user.getId());
        if (BeanUtil.isEmpty(saasUserTask)) {
            return;
        }
        if (!saasUserTask.getFulfilStatus()) {
            return;
        }
        if (saasUserTask.getStatus()) {
            return;
        }

        // 有可能有人不满足获取奖励的条件,直接完成,不领取
        if (saasUserTask.getTaskAwardId() == null) {
            // 任务领取成功,修改状态为已领取
            saasUserTask.setStatus(Boolean.TRUE);
            saasUserTask.setGetTime(DateUtil.date());
            saasUserTask.updateById();
            return;
        }
        SaasTask saasTask = saasTaskDao.getById(saasUserTask.getSaasTaskId());
        List<SaasTaskAwardDetails> saasTaskAwardDetailsList = saasTaskAwardDetailsDao.getByTaskAwardIdAndTaskId(saasUserTask.getTaskAwardId(), saasUserTask.getSaasTaskId());
        saasTaskAwardDetailsList.forEach(saasTaskAwardDetails -> {
            if (saasTaskAwardDetails.getBoxEquityType()==BoxEquityTypeEnum.POINTS) {
                userAssetsService.addIntegralByUserId(Convert.toBigDecimal(saasTaskAwardDetails.getQuantity()), saasUserTask.getUserId(), CoinCategoryEnum.INTEGRAL, AssetChangeLogEnum.SAAS_TASK_AWARD, saasTaskAwardDetails.getId(), saasTask.getTaskName());
                return;
            }
            // 循环发放对应的凭证奖励.每个里面要先查出来,在调用接口写入进去.
            // 奖励凭证的id
            Long equityPropsId = saasTaskAwardDetails.getEquityPropsId();
            EquityProps equityProps = equityPropsService.getById(equityPropsId);
            userEquityPropsService.addEquityPropsByUser(equityProps, user.getId(), UserEquityPropsGetTypeEnum.SAAS_TASK, saasTaskAwardDetails.getQuantity(), saasTask.getTaskName(), saasTaskAwardDetails.getId(),
                    BigDecimal.ZERO,UserEquityPropsGetTypeEnum.SAAS_TASK,saasTaskAwardDetails.getId());
        });
        // 任务领取成功,修改状态为已领取
        saasUserTask.setStatus(Boolean.TRUE);
        saasUserTask.setGetTime(DateUtil.date());
        if (!saasUserTaskDao.receiveAward(saasUserTask)) {
            throw new GlobalRunTimeException("奖励领取失败");
        }
    }

    @Override
    public List<SaasTaskBuyVO> taskTemplateIsTooLongProcedure(Long id) {
        SaasTaskMeetConditions taskId = saasTaskMeetConditionsDao.getByTaskId(id);
        List<SaasTaskBuyVO> list = new ArrayList<>();
        if (BeanUtil.isEmpty(taskId)) {
            throw new GlobalRunTimeException("任务不存在");
        }
        if (taskId.getTaskType()==SaasTaskTypeEnum.SMELTING_APPOINT_COLLECTION||taskId.getTaskType()==SaasTaskTypeEnum.PASSIVITY_INVITE_SMELTING_APPOINT_COLLECTION) {
            List<SaasTaskMeetConditionsOption> saasTaskMeetConditionsOptions = saasTaskMeetConditionsOptionDao.getByTaskId(id, taskId.getId(), 2);
            List<Long> conditionIds = saasTaskMeetConditionsOptions.stream().map(SaasTaskMeetConditionsOption::getConditionId).collect(Collectors.toList());
            List<SaasTaskDetailsCollectionVO> data = digitalCollectionDao.getCollectionSimplenessByIds(conditionIds);
            data.forEach(saasTaskDetailsCollectionVO -> {
                SaasTaskBuyVO saasTaskBuyVO = new SaasTaskBuyVO();
                saasTaskBuyVO.setCreationContent(saasTaskDetailsCollectionVO.getCreationContent());
                saasTaskBuyVO.setFirstTitle(saasTaskDetailsCollectionVO.getConditionName());
                list.add(saasTaskBuyVO);
            });
            return list;
        }

        // 获取商城藏品
        List<SaasTaskMeetConditionsOption> saasTaskMeetConditionsOptions = saasTaskMeetConditionsOptionDao.getByTaskId(id, taskId.getId(), 3);
        // 根据id,获取商品
        List<Long> conditionIds = saasTaskMeetConditionsOptions.stream().map(SaasTaskMeetConditionsOption::getConditionId).collect(Collectors.toList());
        List<SaasTaskDetailsCollectionVO> data = mallProductDao.getMallProductSimplenessByIds(conditionIds);
        data.forEach(saasTaskDetailsCollectionVO -> {
            SaasTaskBuyVO saasTaskBuyVO = new SaasTaskBuyVO();
            saasTaskBuyVO.setCreationContent(saasTaskDetailsCollectionVO.getCreationContent());
            saasTaskBuyVO.setFirstTitle(saasTaskDetailsCollectionVO.getConditionName());
            list.add(saasTaskBuyVO);
        });
        return list;
    }

    /**
     * 临时判定任务的类型在当前数据库里面是否存在
     * @param type
     * @return
     */
    public Boolean taskTypeExist(SaasTaskTypeEnum type){
        String key = StrUtil.format("{}:{}", RedisKeyEnum.SAAS_TASK_TYPE_EXIST.getKey(), type.name());
        Boolean aBoolean = redisTemplate.hasKey(key);
        if (aBoolean) {
            Object o = redisTemplate.opsForValue().get(key);
            if (Convert.toStr(o).equals("1")) {
                return true;
            }else {
                return false;
            }
        }
        Boolean exist = saasTaskDao.taskTypeExist(type.getCode());
        if (exist) {
            redisTemplate.opsForValue().set(key,"1",2,TimeUnit.HOURS);
            return true;
        }else {
            redisTemplate.opsForValue().set(key,"0",2,TimeUnit.HOURS);
            return false;
        }
    }

    @SneakyThrows
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void  templateAnalysis(SaasTaskBurialPointDTO saasTaskBurialPointDTO) {
        // 临时优化，在这里获取数据库里面当前是否有在启动的该任务类型 如果没有的话，直接pass，不在向下进行分发。可以临时有效阻止消费缓慢的问题。后面在想一些办法进行优化。同时在上架的时候干掉所有缓存。
//        if (!taskTypeExist(saasTaskBurialPointDTO.getTaskType())) {
//            return;
//        }
        String key = StrUtil.format("{}:{}:{}", RedisKeyEnum.SAAS_TASK_.getKey(), saasTaskBurialPointDTO.getUserId(),saasTaskBurialPointDTO.getTaskType());
        RLock lock = redisson.getLock(key);
        // 还要单独写一个是因为需要考虑多次消费的递归问题.
        try {
            if (!lock.tryLock(3, TimeUnit.MINUTES)) {
                throw new GlobalRunTimeException("重新投递,超时了.");
            }
            // 这里收取的是任务埋点,根据任务的埋点,匹配用户的任务,每个任务都有不同的类型.有几个模板写几个独立的.
            if (saasTaskBurialPointDTO.getTaskType().equals(SaasTaskTypeEnum.OPEN_WALLET_FOR_THE_FIRST_TIME)) {
                // 首次开通钱包(通过)
                openWalletForTheFirstTime(saasTaskBurialPointDTO);
            }

            if (saasTaskBurialPointDTO.getTaskType().equals(SaasTaskTypeEnum.FIRST_TIME_OPEN_WALLET_INVITATION)) {
                // 邀请首次开通钱包(通过)
                firstTimeOpenWalletInvitation(saasTaskBurialPointDTO);
            }

            if (saasTaskBurialPointDTO.getTaskType().equals(SaasTaskTypeEnum.PURCHASE_OF_DESIGNATED_COLLECTION)) {
                // 购买指定藏品(通过)
                purchaseOfDesignatedCollection(saasTaskBurialPointDTO);
            }

            if (saasTaskBurialPointDTO.getTaskType().equals(SaasTaskTypeEnum.PURCHASE_SPECIFIED_IP_ITEMS)) {
                // 购买指定IP商品(通过)
                purchaseSpecifiedIpItems(saasTaskBurialPointDTO);
            }
            if (saasTaskBurialPointDTO.getTaskType().equals(SaasTaskTypeEnum.INVITATION_TO_PURCHASE_SPECIFIED_COLLECTIONS)) {
                // 邀请购买指定藏品(完成)
                invitationToPurchaseSpecifiedCollections(saasTaskBurialPointDTO);
            }
            if (saasTaskBurialPointDTO.getTaskType().equals(SaasTaskTypeEnum.NEW_USERS_MAKE_THEIR_FIRST_PURCHASE)) {
                //新用户首次下单(完成)
                firstTimeConsumption(saasTaskBurialPointDTO);
            }
            if (saasTaskBurialPointDTO.getTaskType().equals(SaasTaskTypeEnum.INVITE_NEW_USERS_TO_MAKE_THEIR_FIRST_PURCHASE)) {
                //邀请的新用户首次消费
                firstTimeConsumptionInvitation(saasTaskBurialPointDTO);
            }
            if (saasTaskBurialPointDTO.getTaskType().equals(SaasTaskTypeEnum.FREE_MARKET_PURCHASE_OF_ANY_COLLECTION)) {
                //自由市场累计消费金额
                freeMarketTotalConsumption(saasTaskBurialPointDTO);
            }
            if (saasTaskBurialPointDTO.getTaskType().equals(SaasTaskTypeEnum.BUY_BRAND_HATCHING_ANY_COLLECTION)) {
                //购买品牌孵化任意藏品
                brandIncubationTotalConsumption(saasTaskBurialPointDTO);
            }
            if (saasTaskBurialPointDTO.getTaskType().equals(SaasTaskTypeEnum.PURCHASE_PLATFORM_DEBUT_ANY_COLLECTION)) {
                //购买平台首发
                plantFistSellTotalConsumption(saasTaskBurialPointDTO);
            }
            if (saasTaskBurialPointDTO.getTaskType().equals(SaasTaskTypeEnum.CDK_REDEMPTION_TASK)) {
                //兑换cdk
                cdkExchangeTotalConsumption(saasTaskBurialPointDTO);
            }
            if (saasTaskBurialPointDTO.getTaskType().equals(SaasTaskTypeEnum.COMPOSITE_COLLECTION)) {
                //合成藏品
                compoundNftTotalConsumption(saasTaskBurialPointDTO);
            }
            if (saasTaskBurialPointDTO.getTaskType().equals(SaasTaskTypeEnum.DISASSEMBLE_THE_COLLECTION)) {
                //分解藏品
                decomposeNftTotalConsumption(saasTaskBurialPointDTO);
            }

            if (saasTaskBurialPointDTO.getTaskType().equals(SaasTaskTypeEnum.SMELTING_COLLECTION)) {
                //熔炼藏品
                meltingNftTotalConsumption(saasTaskBurialPointDTO);
            }

            if (saasTaskBurialPointDTO.getTaskType().equals(SaasTaskTypeEnum.ACCUMULATED_CONSUMPTION_AMOUNT)) {
                // 范围累销(藏品或者商城)
                userTotalConsumption(saasTaskBurialPointDTO);
            }

            if (saasTaskBurialPointDTO.getTaskType().equals(SaasTaskTypeEnum.BUSINESS_CARD_BUY)) {
                // 名片任务
                businessCardBuy(saasTaskBurialPointDTO);
            }

            if (saasTaskBurialPointDTO.getTaskType().equals(SaasTaskTypeEnum.SMELTING_APPOINT_COLLECTION)) {
                // 熔炼指定藏品
                smeltingAppointCollection(saasTaskBurialPointDTO);
            }

            if (saasTaskBurialPointDTO.getTaskType().equals(SaasTaskTypeEnum.SMELTING_WILL_COLLECTION)) {
                // 熔炼任意藏品
                smeltingWillCollection(saasTaskBurialPointDTO);
            }

            if (saasTaskBurialPointDTO.getTaskType().equals(SaasTaskTypeEnum.PASSIVITY_INVITE_SMELTING_APPOINT_COLLECTION)) {
                // 邀请熔炼指定藏品
                passivityInviteSmeltingAppointCollection(saasTaskBurialPointDTO);
            }

            if (saasTaskBurialPointDTO.getTaskType().equals(SaasTaskTypeEnum.PASSIVITY_INVITE_SMELTING_WILL_COLLECTION)) {
                // 邀请熔炼藏品
                passivityInviteSmeltingWillCollection(saasTaskBurialPointDTO);
            }

        } catch (InterruptedException e) {
            log.error("任务埋点消费异常,异常信息:{}", e.getMessage());
            throw new GlobalRunTimeException("消费异常,重新投递");
        } finally {
            if (lock.isLocked()) {
                lock.unlock();
            }
        }
    }

    /**
     * 邀请熔炼藏品
     * @param saasTaskBurialPointDTO
     */
    private void passivityInviteSmeltingWillCollection(SaasTaskBurialPointDTO saasTaskBurialPointDTO) {
        // 当前用户的上级,满足哪些任务,把满足的任务获取出来 把进度存储起来.如果他满足10个任务 那么就存储10条.满足了进度以后,直接拿来使用进行一次计算.使用过后,那一条数据就舍弃
        UserInfo userInfo = userInfoDao.getById(saasTaskBurialPointDTO.getUserId());
        if (BeanUtil.isEmpty(userInfo)) {
            log.info("用户不存在");
            return;
        }
        UserInfo recommendUser = userInfoDao.getById(userInfo.getRecommendUserId());
        if (BeanUtil.isEmpty(recommendUser)) {
            log.info("邀请人不存在");
            return;
        }
        String key = StrUtil.format("{}:{}", RedisKeyEnum.SAAS_TASK_.getKey(), recommendUser.getId());
        RLock lock = redisson.getLock(key);
        List<SaasUserTask> list = new ArrayList<>();
        // 获取邀请人的任务
        List<SaasTask> meetTheTask = saasTaskDao.getByTaskTypeAndValid(saasTaskBurialPointDTO.getTaskType(), recommendUser.getId());
        // 把meetTheTask根据firstParticipation进行分组.一组是第一次参与,一组是非首次参与
        Map<Boolean, List<SaasTask>> collect = meetTheTask.stream().collect(Collectors.groupingBy(SaasTask::getFirstParticipation));
        inviteUserFirstSmelting(saasTaskBurialPointDTO, lock, collect.get(Boolean.TRUE), recommendUser, list,Boolean.FALSE,Boolean.TRUE);
        inviteUserFirstSmelting(saasTaskBurialPointDTO, lock, collect.get(Boolean.FALSE), recommendUser, list,Boolean.FALSE,Boolean.FALSE);
    }

    /**
     * 邀请用户熔炼
     *
     * @param saasTaskBurialPointDTO
     * @param lock
     * @param meetTheTask
     * @param recommendUser
     * @param list
     */
    private void inviteUserSmelting(SaasTaskBurialPointDTO saasTaskBurialPointDTO, RLock lock, List<SaasTask> meetTheTask, UserInfo recommendUser, List<SaasUserTask> list,Boolean appoint) {
        if (CollUtil.isEmpty(meetTheTask)) {
            return;
        }
        try {
            if (!lock.tryLock(3,TimeUnit.MINUTES)) {
                throw new GlobalRunTimeException("重新投递,超时了");
            }
            // 根据任务不同,把数据生成新的不同的数据.
            meetTheTask.forEach(saasTask -> {
                if (saasTask.getTaskVisible().equals(SaasTaskVisibleEnum.DAO)) {
                    // 如果这个任务是某个dao的任务的话,那么需要验证这个用户是否在这个dao的网体下.不是直接结束.
                    if (!sublink(saasTask, recommendUser.getId())) {
                        return;
                    }
                }
                // 根据任务的id获取任务的条件
                SaasTaskMeetConditions saasTaskMeetConditions = saasTaskMeetConditionsDao.getByTaskId(saasTask.getId());
                // 任务条件不满足
                if (BeanUtil.isEmpty(saasTaskMeetConditions)) {
                    return;
                }

                if (appoint) {
                    // 根据任务的条件id获取任务的条件选项
                    List<SaasTaskMeetConditionsOption> byTaskIdAndConditionId = saasTaskMeetConditionsOptionDao.getByTaskIdAndConditionId(saasTask.getId(), saasTaskBurialPointDTO.getConditionId(), 2);
                    // 任务条件是空的,证明这个熔炼不是指定的藏品里面的
                    if (CollUtil.isEmpty(byTaskIdAndConditionId)) {
                        return;
                    }
                }

                SaasUserTask bySaasTask = saasUserTaskDao.getBySaasTask(saasTask.getId(), recommendUser.getId());
                if (BeanUtil.isEmpty(bySaasTask)) {
                    // 当前没有执行中的任务,根据配置新增对应的份数,如果大于1的话,那么最后一份是未完成,其他的为已完成.如果为1的话则只完成一份 否则的话是未完成
                    // 配置需要购买的数量
                    BigDecimal configurationCount = saasTaskMeetConditions.getSchedule();
                    // 用户购买的数量
                    BigDecimal userBuyCount = saasTaskBurialPointDTO.getSchedule();
                    // 用户购买数量大于配置的数量,那么就需要新增多份
                    while (true) {
                        if (taskUpperLimit(saasTask, recommendUser.getId())) {
                            break;
                        }
                        SaasUserTask saasUserTask = new SaasUserTask();
                        saasUserTask.setSaasTaskId(saasTask.getId());
                        saasUserTask.setTaskTrace(saasTask.getTaskTrace());
                        saasUserTask.setUserId(recommendUser.getId());
                        saasUserTask.setTaskType(saasTaskBurialPointDTO.getTaskType());
                        if (NumberUtil.isLessOrEqual(userBuyCount, BigDecimal.ZERO)) {
                            break;
                        }
                        // 当购买数值比配置数值大的时候,就给直接完成的数据
                        if (NumberUtil.isGreater(userBuyCount, configurationCount)) {
                            // 任务数量是否足够
                            if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                                break;
                            }
                            saasUserTask.setSchedule(configurationCount);
                            saasUserTask.setVoluntarySum(0);
                            saasUserTask.setStatus(Boolean.FALSE);
                            saasUserTask.setFulfilStatus(Boolean.TRUE);
                            saasUserTask.setAccomplishSum(accomplishSum(saasTask, recommendUser.getId()));
                            saasUserTask.setFulfilTime(DateUtil.date());
                            TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask,  recommendUser.getId());
                            saasUserTask.setSaasType(saasTask.getSaasType());
                            saasUserTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                            saasUserTask.setStageId(taskAwardIdAndStageId.getStageId());
                            saasUserTask.setOverTime(saasTask.getTaskEnd());
                            // 自己的数据减去配置的数据,作为下一次循环的依据
                            userBuyCount = userBuyCount.subtract(configurationCount);
                        } else if (NumberUtil.equals(userBuyCount, configurationCount)) {
                            if (taskUpperLimit(saasTask, recommendUser.getId())) {
                                break;
                            }
                            if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                                break;
                            }
                            saasUserTask.setSchedule(configurationCount);
                            saasUserTask.setVoluntarySum(0);
                            saasUserTask.setStatus(Boolean.FALSE);
                            saasUserTask.setFulfilStatus(Boolean.TRUE);
                            saasUserTask.setAccomplishSum(accomplishSum(saasTask,  recommendUser.getId()));
                            saasUserTask.setFulfilTime(DateUtil.date());
                            TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask,  recommendUser.getId());
                            saasUserTask.setSaasType(saasTask.getSaasType());
                            saasUserTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                            saasUserTask.setStageId(taskAwardIdAndStageId.getStageId());
                            saasUserTask.setOverTime(saasTask.getTaskEnd());
                            userBuyCount = BigDecimal.ZERO;
                        } else {
                            // 否则就给未完成的数据
                            saasUserTask.setSchedule(userBuyCount);
                            saasUserTask.setFulfilStatus(Boolean.FALSE);
                            saasUserTask.setOverTime(saasTask.getTaskEnd());
                            saasUserTask.setSaasType(saasTask.getSaasType());
                            userBuyCount = BigDecimal.ZERO;
                        }
                        saasUserTask.insert();
                        list.add(saasUserTask);
                    }
                } else {
                    // 当存在任务的时候,则已经触发的任务加上这次的购买数量,如果大于配置的数量,那么就是完成的,否则就是未完成的,并且把多出来的部分生成一个新的任务
                    // 配置
                    BigDecimal configurationCount = saasTaskMeetConditions.getSchedule();
                    BigDecimal add = bySaasTask.getSchedule().add(saasTaskBurialPointDTO.getSchedule());
                    // 修改的同时,还要把多余的部分新增
                    if (NumberUtil.isGreater(add, configurationCount)) {
                        if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                            return;
                        }
                        if (taskUpperLimit(saasTask,  recommendUser.getId())) {
                            return;
                        }
                        bySaasTask.setSchedule(configurationCount);
                        bySaasTask.setFulfilTime(DateUtil.date());
                        bySaasTask.setFulfilStatus(Boolean.TRUE);
                        bySaasTask.setAccomplishSum(accomplishSum(saasTask,  recommendUser.getId()));
                        TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask,  recommendUser.getId());
                        bySaasTask.setSaasType(saasTask.getSaasType());
                        bySaasTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                        bySaasTask.setStageId(taskAwardIdAndStageId.getStageId());

                        bySaasTask.updateById();
                        list.add(bySaasTask);
                        // 获取多余部分,用用户的额度+购买的额度-配置的额度就是剩余的额度
                        BigDecimal userBuyCount = add.subtract(configurationCount);
                        while (true) {
                            if (taskUpperLimit(saasTask,  recommendUser.getId())) {
                                break;
                            }
                            SaasUserTask saasUserTask = new SaasUserTask();
                            saasUserTask.setSaasTaskId(saasTask.getId());
                            saasUserTask.setTaskTrace(saasTask.getTaskTrace());
                            saasUserTask.setUserId( recommendUser.getId());
                            saasUserTask.setTaskType(saasTaskBurialPointDTO.getTaskType());
                            if (NumberUtil.isLessOrEqual(userBuyCount, BigDecimal.ZERO)) {
                                break;
                            }
                            // 当购买数值比配置数值大的时候,就给直接完成的数据
                            if (NumberUtil.isGreater(userBuyCount, configurationCount)) {
                                saasUserTask.setSchedule(configurationCount);
                                saasUserTask.setVoluntarySum(0);
                                saasUserTask.setStatus(Boolean.FALSE);
                                saasUserTask.setFulfilStatus(Boolean.TRUE);
                                saasUserTask.setAccomplishSum(accomplishSum(saasTask,  recommendUser.getId()));
                                saasUserTask.setFulfilTime(DateUtil.date());
                                TaskAwardIdAndStageIdVO taskAwardIdAndStageIdResult = getTaskAwardIdAndStageId(saasTask,  recommendUser.getId());
                                saasUserTask.setSaasType(saasTask.getSaasType());
                                saasUserTask.setTaskAwardId(taskAwardIdAndStageIdResult.getAwardId());
                                saasUserTask.setStageId(taskAwardIdAndStageIdResult.getStageId());
                                saasUserTask.setOverTime(saasTask.getTaskEnd());
                                // 自己的数据减去配置的数据,作为下一次循环的依据
                                userBuyCount = userBuyCount.subtract(configurationCount);
                                if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                                    break;
                                }
                            } else {
                                // 否则就给未完成的数据
                                saasUserTask.setSchedule(userBuyCount);
                                saasUserTask.setFulfilStatus(Boolean.FALSE);
                                saasUserTask.setOverTime(saasTask.getTaskEnd());
                                saasUserTask.setSaasType(saasTask.getSaasType());
                                userBuyCount = BigDecimal.ZERO;
                            }
                            saasUserTask.insert();
                            list.add(saasUserTask);
                        }
                    }

                    // 修改的同时不新增.并且也不完成任务
                    if (NumberUtil.isLess(add, configurationCount)) {
                        bySaasTask.setSchedule(add);
                        bySaasTask.updateById();
                    }

                    // 修改本条为完成任务
                    if (NumberUtil.equals(add, configurationCount)) {
                        if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                            return;
                        }
                        if (taskUpperLimit(saasTask,  recommendUser.getId())) {
                            return;
                        }
                        bySaasTask.setSchedule(add);
                        bySaasTask.setFulfilTime(DateUtil.date());
                        bySaasTask.setFulfilStatus(Boolean.TRUE);
                        bySaasTask.setAccomplishSum(accomplishSum(saasTask,  recommendUser.getId()));
                        TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask,  recommendUser.getId());
                        bySaasTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                        bySaasTask.setStageId(taskAwardIdAndStageId.getStageId());
                        bySaasTask.setSaasType(saasTask.getSaasType());
                        bySaasTask.updateById();
                        list.add(bySaasTask);
                    }
                }

            });
            addSaasTaskDrawPrize(list);
        } catch (Exception e) {
            log.info("邀请熔炼任意藏品,异常信息:{},请求参数:{}", e.getMessage(), JSON.toJSON(saasTaskBurialPointDTO));
            e.fillInStackTrace();
        } finally {
            if (lock.isLocked()&& lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }

    /**
     * 邀请用户第一次熔炼
     * @param saasTaskBurialPointDTO
     * @param lock
     * @param meetTheTask
     * @param recommendUser
     * @param list
     */
    private void inviteUserFirstSmelting(SaasTaskBurialPointDTO saasTaskBurialPointDTO, RLock lock, List<SaasTask> meetTheTask, UserInfo recommendUser, List<SaasUserTask> list,Boolean appoint,Boolean first) {
        // 瀚海龙吟熔炼排除
        if (saasTaskBurialPointDTO.getConditionId().equals(852L)) {
            return;
        }
        if (CollUtil.isEmpty(meetTheTask)) {
            return;
        }
        try {
            if (!lock.tryLock(3,TimeUnit.MINUTES)) {
                throw new GlobalRunTimeException("重新投递,超时了");
            }
            // 根据任务不同,把数据生成新的不同的数据.
            meetTheTask.forEach(saasTask -> {
                // 查看用户是否在这个DAO下
                if (saasTask.getTaskVisible().equals(SaasTaskVisibleEnum.DAO)) {
                    // 如果这个任务是某个dao的任务的话,那么需要验证这个用户是否在这个dao的网体下.不是直接结束.
                    if (!sublink(saasTask, recommendUser.getId())) {
                        return;
                    }
                }
                // 根据任务的id获取任务的条件
                SaasTaskMeetConditions saasTaskMeetConditions = saasTaskMeetConditionsDao.getByTaskId(saasTask.getId());
                // 任务条件不满足
                if (BeanUtil.isEmpty(saasTaskMeetConditions)) {
                    return;
                }

                if (appoint) {
                    // 根据任务的条件id获取任务的条件选项
                    List<SaasTaskMeetConditionsOption> byTaskIdAndConditionId = saasTaskMeetConditionsOptionDao.getByTaskIdAndConditionId(saasTask.getId(), saasTaskBurialPointDTO.getConditionId(), 2);
                    // 任务条件是空的,证明这个熔炼不是指定的藏品里面的
                    if (CollUtil.isEmpty(byTaskIdAndConditionId)) {
                        return;
                    }
                }

                if (first && appoint) {
                    // 如果是首次并且指定了藏品类型则必须是这个藏品首次熔炼 否则才是必须完全是首次熔炼
                    // 当前用户在熔炼表里面没有任何的数据,那么就新增一条数据 否则的话就不是第一次熔炼,要减去他当前的数值.
                    if (userEcologyHatchRecordsDao.getUserSum(saasTaskBurialPointDTO.getUserId(), saasTaskBurialPointDTO.getConditionId()) - Convert.toInt(saasTaskBurialPointDTO.getSchedule()) > 0) {
                        return;
                    }
                } else if (first){
                    // 当前用户在熔炼表里面没有任何的数据,那么就新增一条数据 否则的话就不是第一次熔炼,要减去他当前的数值.
                    if (userEcologyHatchRecordsDao.getUserSum(saasTaskBurialPointDTO.getUserId(),0L) - Convert.toInt(saasTaskBurialPointDTO.getSchedule()) > 0) {
                        return;
                    }
                }
                // 先获取用户当前的存档是否存在,如果不存在的话,那么就新增一条,如果存在的话,那么就修改这条数据
                SaasTaskUserRecord saasTaskUserRecord = saasTaskUserRecordDao.getSaasTaskIdAndUserIdAndTaskTrace(saasTask.getId(), recommendUser.getId(), saasTaskBurialPointDTO.getUserId(), saasTask.getTaskTrace());
                if (BeanUtil.isEmpty(saasTaskUserRecord)) {
                    // 新增一条新的
                    SaasTaskUserRecord save = new SaasTaskUserRecord();
                    save.setSaasTaskId(saasTask.getId());
                    save.setUserId(recommendUser.getId());
                    save.setOfferUserId(saasTaskBurialPointDTO.getUserId());
                    save.setTaskTrace(saasTask.getTaskTrace());
                    save.setSchedule(saasTaskBurialPointDTO.getSchedule());
                    save.setTaskType(saasTaskBurialPointDTO.getTaskType());
                    save.insert();
                } else {
                    // 修改这条数据
                    saasTaskUserRecord.setSchedule(saasTaskUserRecord.getSchedule().add(saasTaskBurialPointDTO.getSchedule()));
                    saasTaskUserRecord.updateById();
                }
            });
            // 根据邀请人任务,开始计算任务的进度
            for (SaasTask saasTask : meetTheTask) {
                if (taskUpperLimit(saasTask, recommendUser.getId())) {
                    continue;
                }
                // 根据任务的id,资源提供者和受益者的id.获取数据,如果有的话.根据任务的配置,进行计算.如果没有的话,那么就不计算
                SaasTaskUserRecord saasTaskUserRecord = saasTaskUserRecordDao.getSaasTaskIdAndUserIdAndTaskTrace(saasTask.getId(), recommendUser.getId(), saasTaskBurialPointDTO.getUserId(), saasTask.getTaskTrace());
                if (BeanUtil.isEmpty(saasTaskUserRecord)) {
                    continue;
                }
                // 该用户已经参与过一次该任务的计算
                if (saasTaskUserRecord.getCalculate()) {
                    continue;
                }
                // 存在的情况根据配置进行计算
                SaasTaskMeetConditions saasTaskMeetConditions = saasTaskMeetConditionsDao.getByTaskId(saasTask.getId());
                // 配置
                BigDecimal configuration = saasTaskMeetConditions.getSchedule();
                // 进度
                BigDecimal schedule = saasTaskUserRecord.getSchedule();
                if (NumberUtil.isGreaterOrEqual(schedule, configuration)) {
                    // 如果说他算一个,那么这个受益用户的任务进度+1,一个版本(周期),一个用户只会提供一次受益.不会提供多次.
                    SaasUserTask bySaasTask = saasUserTaskDao.getBySaasTask(saasTask.getId(), recommendUser.getId());
                    if (BeanUtil.isEmpty(bySaasTask)) {
                        SaasUserTask saasUserTask = new SaasUserTask();
                        saasUserTask.setSaasTaskId(saasTask.getId());
                        saasUserTask.setTaskTrace(saasTask.getTaskTrace());
                        saasUserTask.setUserId(recommendUser.getId());
                        saasUserTask.setTaskType(saasTaskBurialPointDTO.getTaskType());
                        saasUserTask.setVoluntarySum(1);
                        if (saasTaskMeetConditions.getVoluntarySum() == saasUserTask.getVoluntarySum()) {
                            saasUserTask.setFulfilStatus(Boolean.TRUE);
                            TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, recommendUser.getId());
                            saasUserTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                            saasUserTask.setStageId(taskAwardIdAndStageId.getStageId());
                            saasUserTask.setAccomplishSum(accomplishSum(saasTask, recommendUser.getId()));
                            saasUserTask.setFulfilTime(DateUtil.date());
                            // 任务数量是否足够
                            if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                                continue;
                            }
                        }
                        saasUserTask.setOverTime(saasTask.getTaskEnd());
                        saasTaskUserRecord.setCalculate(Boolean.TRUE);
                        saasTaskUserRecord.updateById();
                        saasUserTask.setSaasType(saasTask.getSaasType());
                        saasUserTask.insert();
                        list.add(saasUserTask);
                    } else {
                        bySaasTask.setVoluntarySum(bySaasTask.getVoluntarySum() + 1);
                        saasTaskUserRecord.setCalculate(Boolean.TRUE);
                        // 判定是否完成任务
                        if (bySaasTask.getVoluntarySum() >= saasTaskMeetConditions.getVoluntarySum()) {
                            // 任务数量是否足够
                            if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                                continue;
                            }
                            bySaasTask.setFulfilStatus(Boolean.TRUE);
                            bySaasTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                            TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, recommendUser.getId());
                            bySaasTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                            bySaasTask.setStageId(taskAwardIdAndStageId.getStageId());
                            bySaasTask.setSaasType(saasTask.getSaasType());
                            bySaasTask.setFulfilTime(DateUtil.date());
                        }
                        saasTaskUserRecord.updateById();
                        bySaasTask.updateById();
                        list.add(bySaasTask);
                    }
                }
            }
            addSaasTaskDrawPrize(list);
        } catch (Exception e) {
            log.info("邀请熔炼任意藏品,异常信息:{},请求参数:{}", e.getMessage(), JSON.toJSON(saasTaskBurialPointDTO));
            e.fillInStackTrace();
        } finally {
            if (lock.isLocked()&& lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }

    /**
     * 邀请熔炼指定藏品
     * @param saasTaskBurialPointDTO
     */
    private void passivityInviteSmeltingAppointCollection(SaasTaskBurialPointDTO saasTaskBurialPointDTO) {
        // 当前用户的上级,满足哪些任务,把满足的任务获取出来 把进度存储起来.如果他满足10个任务 那么就存储10条.满足了进度以后,直接拿来使用进行一次计算.使用过后,那一条数据就舍弃
        UserInfo userInfo = userInfoDao.getById(saasTaskBurialPointDTO.getUserId());
        if (BeanUtil.isEmpty(userInfo)) {
            log.info("用户不存在");
            return;
        }
        UserInfo recommendUser = userInfoDao.getById(userInfo.getRecommendUserId());
        if (BeanUtil.isEmpty(recommendUser)) {
            log.info("邀请人不存在");
            return;
        }
        String key = StrUtil.format("{}:{}", RedisKeyEnum.SAAS_TASK_.getKey(), recommendUser.getId());
        RLock lock = redisson.getLock(key);
        List<SaasUserTask> list = new ArrayList<>();
        // 获取邀请人的任务
        List<SaasTask> meetTheTask = saasTaskDao.getByTaskTypeAndValid(saasTaskBurialPointDTO.getTaskType(), recommendUser.getId());
        // 把meetTheTask根据firstParticipation进行分组.一组是第一次参与,一组是非首次参与
        Map<Boolean, List<SaasTask>> collect = meetTheTask.stream().collect(Collectors.groupingBy(SaasTask::getFirstParticipation));
        inviteUserFirstSmelting(saasTaskBurialPointDTO, lock, collect.get(Boolean.TRUE), recommendUser, list,Boolean.TRUE,Boolean.TRUE);
        inviteUserFirstSmelting(saasTaskBurialPointDTO, lock, collect.get(Boolean.FALSE), recommendUser, list,Boolean.TRUE,Boolean.FALSE);
    }

    /**
     * 熔炼任意藏品
     * @param saasTaskBurialPointDTO
     */
    private void smeltingWillCollection(SaasTaskBurialPointDTO saasTaskBurialPointDTO) {
        //  获取符合条件的任务
        List<SaasTask> meetTheTask = saasTaskDao.getByTaskTypeAndValid(saasTaskBurialPointDTO.getTaskType(), saasTaskBurialPointDTO.getUserId());
        saasTaskBurialPointDTO.setValid(meetTheTask);
        // 获取任务的条件
        List<SaasUserTask> list = new ArrayList<>();
        meetTheTask.forEach(saasTask -> {

            if (saasTask.getTaskVisible().equals(SaasTaskVisibleEnum.DAO)) {
                // 如果这个任务是某个dao的任务的话,那么需要验证这个用户是否在这个dao的网体下.不是直接结束.
                if (!sublink(saasTask, saasTaskBurialPointDTO.getUserId())) {
                    return;
                }
            }
            // 根据任务的id获取任务的条件
            SaasTaskMeetConditions saasTaskMeetConditions = saasTaskMeetConditionsDao.getByTaskId(saasTask.getId());
            // 任务条件不满足
            if (BeanUtil.isEmpty(saasTaskMeetConditions)) {
                return;
            }

            /*
            用户购买的不是空的,证明用户购买是命中了的.并且他因为只要能查询出来的任务就可以去完成的.所以这里需要考虑到他的任务数量.
            1.考虑任务的剩余数量进度问题.要在修改的时候做判定.虽然查询出来的时候有大于0判定,但是要考虑事务以及并发的问题.所以一旦出现了数量不符就要回滚.
            2.考虑他超出的部分的问题,他有可能会出现有多条的情况.所以在修改原本的一条的时候,多余的部分 需要新生成多条.这个条目根据任务的配置来.
            * */
            SaasUserTask bySaasTask = saasUserTaskDao.getBySaasTask(saasTask.getId(), saasTaskBurialPointDTO.getUserId());
            if (BeanUtil.isEmpty(bySaasTask)) {
                // 当前没有执行中的任务,根据配置新增对应的份数,如果大于1的话,那么最后一份是未完成,其他的为已完成.如果为1的话则只完成一份 否则的话是未完成
                // 配置需要购买的数量
                BigDecimal configurationCount = saasTaskMeetConditions.getSchedule();
                // 用户购买的数量
                BigDecimal userBuyCount = saasTaskBurialPointDTO.getSchedule();
                // 用户购买数量大于配置的数量,那么就需要新增多份
                while (true) {
                    if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                        break;
                    }
                    SaasUserTask saasUserTask = new SaasUserTask();
                    saasUserTask.setSaasTaskId(saasTask.getId());
                    saasUserTask.setTaskTrace(saasTask.getTaskTrace());
                    saasUserTask.setUserId(saasTaskBurialPointDTO.getUserId());
                    saasUserTask.setTaskType(saasTaskBurialPointDTO.getTaskType());
                    if (NumberUtil.isLessOrEqual(userBuyCount, BigDecimal.ZERO)) {
                        break;
                    }
                    // 当购买数值比配置数值大的时候,就给直接完成的数据
                    if (NumberUtil.isGreater(userBuyCount, configurationCount)) {
                        // 任务数量是否足够
                        if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                            break;
                        }
                        saasUserTask.setSchedule(configurationCount);
                        saasUserTask.setVoluntarySum(0);
                        saasUserTask.setStatus(Boolean.FALSE);
                        saasUserTask.setFulfilStatus(Boolean.TRUE);
                        saasUserTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                        saasUserTask.setFulfilTime(DateUtil.date());
                        TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                        saasUserTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                        saasUserTask.setStageId(taskAwardIdAndStageId.getStageId());
                        saasUserTask.setSaasType(saasTask.getSaasType());
                        saasUserTask.setOverTime(saasTask.getTaskEnd());
                        // 自己的数据减去配置的数据,作为下一次循环的依据
                        userBuyCount = userBuyCount.subtract(configurationCount);
                    } else if (NumberUtil.equals(userBuyCount, configurationCount)) {
                        if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                            break;
                        }
                        saasUserTask.setSchedule(configurationCount);
                        saasUserTask.setVoluntarySum(0);
                        saasUserTask.setStatus(Boolean.FALSE);
                        saasUserTask.setFulfilStatus(Boolean.TRUE);
                        saasUserTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                        saasUserTask.setFulfilTime(DateUtil.date());
                        TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                        saasUserTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                        saasUserTask.setStageId(taskAwardIdAndStageId.getStageId());
                        saasUserTask.setSaasType(saasTask.getSaasType());
                        saasUserTask.setOverTime(saasTask.getTaskEnd());
                        userBuyCount = BigDecimal.ZERO;
                    } else {
                        // 否则就给未完成的数据
                        saasUserTask.setSchedule(userBuyCount);
                        saasUserTask.setFulfilStatus(Boolean.FALSE);
                        saasUserTask.setOverTime(saasTask.getTaskEnd());
                        saasUserTask.setSaasType(saasTask.getSaasType());
                        userBuyCount = BigDecimal.ZERO;
                    }
                    saasUserTask.insert();
                    list.add(saasUserTask);
                }
            } else {
                // 当存在任务的时候,则已经触发的任务加上这次的购买数量,如果大于配置的数量,那么就是完成的,否则就是未完成的,并且把多出来的部分生成一个新的任务
                // 配置
                BigDecimal configurationCount = saasTaskMeetConditions.getSchedule();
                BigDecimal add = bySaasTask.getSchedule().add(saasTaskBurialPointDTO.getSchedule());
                // 修改的同时,还要把多余的部分新增
                if (NumberUtil.isGreater(add, configurationCount)) {
                    if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                        return;
                    }
                    if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                        return;
                    }
                    bySaasTask.setSchedule(configurationCount);
                    bySaasTask.setFulfilTime(DateUtil.date());
                    bySaasTask.setFulfilStatus(Boolean.TRUE);
                    bySaasTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                    TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                    bySaasTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                    bySaasTask.setSaasType(saasTask.getSaasType());
                    bySaasTask.setStageId(taskAwardIdAndStageId.getStageId());
                    bySaasTask.updateById();
                    // 获取多余部分,用用户的额度+购买的额度-配置的额度就是剩余的额度
                    list.add(bySaasTask);
                    BigDecimal userBuyCount = add.subtract(configurationCount);
                    while (true) {
                        if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                            break;
                        }
                        SaasUserTask saasUserTask = new SaasUserTask();
                        saasUserTask.setSaasTaskId(saasTask.getId());
                        saasUserTask.setTaskTrace(saasTask.getTaskTrace());
                        saasUserTask.setUserId(saasTaskBurialPointDTO.getUserId());
                        saasUserTask.setTaskType(saasTaskBurialPointDTO.getTaskType());
                        if (NumberUtil.isLessOrEqual(userBuyCount, BigDecimal.ZERO)) {
                            break;
                        }
                        // 当购买数值比配置数值大的时候,就给直接完成的数据
                        if (NumberUtil.isGreater(userBuyCount, configurationCount)) {
                            saasUserTask.setSchedule(configurationCount);
                            saasUserTask.setVoluntarySum(0);
                            saasUserTask.setStatus(Boolean.FALSE);
                            saasUserTask.setFulfilStatus(Boolean.TRUE);
                            saasUserTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                            saasUserTask.setFulfilTime(DateUtil.date());
                            TaskAwardIdAndStageIdVO taskAwardIdAndStageIdResult = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                            saasUserTask.setTaskAwardId(taskAwardIdAndStageIdResult.getAwardId());
                            saasUserTask.setSaasType(saasTask.getSaasType());
                            saasUserTask.setStageId(taskAwardIdAndStageIdResult.getStageId());
                            saasUserTask.setOverTime(saasTask.getTaskEnd());
                            // 自己的数据减去配置的数据,作为下一次循环的依据
                            userBuyCount = userBuyCount.subtract(configurationCount);
                            if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                                break;
                            }
                        } else {
                            // 否则就给未完成的数据
                            saasUserTask.setSchedule(userBuyCount);
                            saasUserTask.setFulfilStatus(Boolean.FALSE);
                            saasUserTask.setOverTime(saasTask.getTaskEnd());
                            saasUserTask.setSaasType(saasTask.getSaasType());
                            userBuyCount = BigDecimal.ZERO;
                        }
                        saasUserTask.insert();
                        list.add(saasUserTask);
                    }
                }

                // 修改的同时不新增.并且也不完成任务
                if (NumberUtil.isLess(add, configurationCount)) {
                    bySaasTask.setSchedule(add);
                    bySaasTask.updateById();
                }

                // 修改本条为完成任务
                if (NumberUtil.equals(add, configurationCount)) {
                    if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                        return;
                    }
                    if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                        return;
                    }
                    bySaasTask.setSchedule(add);
                    bySaasTask.setFulfilTime(DateUtil.date());
                    bySaasTask.setFulfilStatus(Boolean.TRUE);
                    bySaasTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                    TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                    bySaasTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                    bySaasTask.setSaasType(saasTask.getSaasType());
                    bySaasTask.setStageId(taskAwardIdAndStageId.getStageId());
                    bySaasTask.updateById();
                    list.add(bySaasTask);
                }
            }
        });
        addSaasTaskDrawPrize(list);
    }

    /**
     * 熔炼指定藏品.
     * @param saasTaskBurialPointDTO
     */
    private void smeltingAppointCollection(SaasTaskBurialPointDTO saasTaskBurialPointDTO) {
        //  获取符合条件的任务
        List<SaasTask> meetTheTask = saasTaskDao.getByTaskTypeAndValid(saasTaskBurialPointDTO.getTaskType(), saasTaskBurialPointDTO.getUserId());
        saasTaskBurialPointDTO.setValid(meetTheTask);
        // 获取任务的条件
        List<SaasUserTask> list = new ArrayList<>();
        meetTheTask.forEach(saasTask -> {
            if (saasTask.getTaskVisible().equals(SaasTaskVisibleEnum.DAO)) {
                // 如果这个任务是某个dao的任务的话,那么需要验证这个用户是否在这个dao的网体下.不是直接结束.
                if (!sublink(saasTask, saasTaskBurialPointDTO.getUserId())) {
                    return;
                }
            }

            // 根据任务的id获取任务的条件
            SaasTaskMeetConditions saasTaskMeetConditions = saasTaskMeetConditionsDao.getByTaskId(saasTask.getId());
            // 任务条件不满足
            if (BeanUtil.isEmpty(saasTaskMeetConditions)) {
                return;
            }
            // 根据任务的条件id获取任务的条件选项
            List<SaasTaskMeetConditionsOption> byTaskIdAndConditionId = saasTaskMeetConditionsOptionDao.getByTaskIdAndConditionId(saasTask.getId(), saasTaskBurialPointDTO.getConditionId(), 2);
            // 任务条件是空的,证明这个熔炼不是指定的藏品里面的
            if (CollUtil.isEmpty(byTaskIdAndConditionId)) {
                return;
            }


            /*
            用户购买的不是空的,证明用户购买是命中了的.并且他因为只要能查询出来的任务就可以去完成的.所以这里需要考虑到他的任务数量.
            1.考虑任务的剩余数量进度问题.要在修改的时候做判定.虽然查询出来的时候有大于0判定,但是要考虑事务以及并发的问题.所以一旦出现了数量不符就要回滚.
            2.考虑他超出的部分的问题,他有可能会出现有多条的情况.所以在修改原本的一条的时候,多余的部分 需要新生成多条.这个条目根据任务的配置来.
            * */
            SaasUserTask bySaasTask = saasUserTaskDao.getBySaasTask(saasTask.getId(), saasTaskBurialPointDTO.getUserId());
            if (BeanUtil.isEmpty(bySaasTask)) {
                // 当前没有执行中的任务,根据配置新增对应的份数,如果大于1的话,那么最后一份是未完成,其他的为已完成.如果为1的话则只完成一份 否则的话是未完成
                // 配置需要熔炼的数量
                BigDecimal configurationCount = saasTaskMeetConditions.getSchedule();
                // 用户熔炼的数量
                BigDecimal userBuyCount = saasTaskBurialPointDTO.getSchedule();
                // 用户购买数量大于配置的数量,那么就需要新增多份
                while (true) {
                    if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                        break;
                    }
                    SaasUserTask saasUserTask = new SaasUserTask();
                    saasUserTask.setSaasTaskId(saasTask.getId());
                    saasUserTask.setTaskTrace(saasTask.getTaskTrace());
                    saasUserTask.setUserId(saasTaskBurialPointDTO.getUserId());
                    saasUserTask.setTaskType(saasTaskBurialPointDTO.getTaskType());
                    if (NumberUtil.isLessOrEqual(userBuyCount, BigDecimal.ZERO)) {
                        break;
                    }
                    // 当购买数值比配置数值大的时候,就给直接完成的数据
                    if (NumberUtil.isGreater(userBuyCount, configurationCount)) {
                        // 任务数量是否足够
                        if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                            break;
                        }
                        saasUserTask.setSchedule(configurationCount);
                        saasUserTask.setVoluntarySum(0);
                        saasUserTask.setStatus(Boolean.FALSE);
                        saasUserTask.setFulfilStatus(Boolean.TRUE);
                        saasUserTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                        saasUserTask.setFulfilTime(DateUtil.date());
                        TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                        saasUserTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                        saasUserTask.setSaasType(saasTask.getSaasType());
                        saasUserTask.setStageId(taskAwardIdAndStageId.getStageId());
                        saasUserTask.setOverTime(saasTask.getTaskEnd());
                        // 自己的数据减去配置的数据,作为下一次循环的依据
                        userBuyCount = userBuyCount.subtract(configurationCount);
                    } else if (NumberUtil.equals(userBuyCount, configurationCount)) {
                        // 任务数量是否足够
                        if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                            break;
                        }
                        // 否则就给未完成的数据
                        saasUserTask.setSchedule(configurationCount);
                        saasUserTask.setVoluntarySum(0);
                        saasUserTask.setStatus(Boolean.FALSE);
                        saasUserTask.setFulfilStatus(Boolean.TRUE);
                        saasUserTask.setFulfilTime(DateUtil.date());
                        saasUserTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                        TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                        saasUserTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                        saasUserTask.setSaasType(saasTask.getSaasType());
                        saasUserTask.setStageId(taskAwardIdAndStageId.getStageId());
                        saasUserTask.setOverTime(saasTask.getTaskEnd());
                        userBuyCount = BigDecimal.ZERO;
                    } else {
                        // 否则就给未完成的数据
                        saasUserTask.setSchedule(userBuyCount);
                        saasUserTask.setFulfilStatus(Boolean.FALSE);
                        saasUserTask.setOverTime(saasTask.getTaskEnd());
                        saasUserTask.setSaasType(saasTask.getSaasType());
                        userBuyCount = BigDecimal.ZERO;
                    }
                    saasUserTask.insert();
                    list.add(saasUserTask);
                }
            } else {
                // 当存在任务的时候,则已经触发的任务加上这次的购买数量,如果大于配置的数量,那么就是完成的,否则就是未完成的,并且把多出来的部分生成一个新的任务
                // 配置
                BigDecimal configurationCount = saasTaskMeetConditions.getSchedule();
                BigDecimal add = bySaasTask.getSchedule().add(saasTaskBurialPointDTO.getSchedule());
                // 修改的同时,还要把多余的部分新增
                if (NumberUtil.isGreater(add, configurationCount)) {
                    // 任务数量是否足够
                    if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                        return;
                    }

                    if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                        return;
                    }
                    bySaasTask.setSchedule(configurationCount);
                    bySaasTask.setFulfilTime(DateUtil.date());
                    bySaasTask.setFulfilStatus(Boolean.TRUE);
                    bySaasTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                    TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                    bySaasTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                    bySaasTask.setSaasType(saasTask.getSaasType());
                    bySaasTask.setStageId(taskAwardIdAndStageId.getStageId());
                    bySaasTask.updateById();
                    list.add(bySaasTask);
                    // 获取多余部分,用用户的额度+购买的额度-配置的额度就是剩余的额度
                    BigDecimal userBuyCount = add.subtract(configurationCount);
                    while (true) {
                        if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                            return;
                        }
                        SaasUserTask saasUserTask = new SaasUserTask();
                        saasUserTask.setSaasTaskId(saasTask.getId());
                        saasUserTask.setTaskTrace(saasTask.getTaskTrace());
                        saasUserTask.setUserId(saasTaskBurialPointDTO.getUserId());
                        saasUserTask.setTaskType(saasTaskBurialPointDTO.getTaskType());
                        if (NumberUtil.isLessOrEqual(userBuyCount, BigDecimal.ZERO)) {
                            break;
                        }
                        // 当购买数值比配置数值大的时候,就给直接完成的数据
                        if (NumberUtil.isGreater(userBuyCount, configurationCount)) {
                            // 任务数量是否足够
                            if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                                return;
                            }
                            saasUserTask.setSchedule(configurationCount);
                            saasUserTask.setVoluntarySum(0);
                            saasUserTask.setStatus(Boolean.FALSE);
                            saasUserTask.setFulfilStatus(Boolean.TRUE);
                            saasUserTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                            saasUserTask.setFulfilTime(DateUtil.date());
                            TaskAwardIdAndStageIdVO taskAwardIdAndStageId1 = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                            saasUserTask.setTaskAwardId(taskAwardIdAndStageId1.getAwardId());
                            saasUserTask.setSaasType(saasTask.getSaasType());
                            saasUserTask.setStageId(taskAwardIdAndStageId1.getStageId());
                            saasUserTask.setOverTime(saasTask.getTaskEnd());
                            // 自己的数据减去配置的数据,作为下一次循环的依据
                            userBuyCount = userBuyCount.subtract(configurationCount);
                        } else {
                            // 否则就给未完成的数据
                            saasUserTask.setSchedule(userBuyCount);
                            saasUserTask.setFulfilStatus(Boolean.FALSE);
                            saasUserTask.setOverTime(saasTask.getTaskEnd());
                            saasUserTask.setSaasType(saasTask.getSaasType());
                            userBuyCount = BigDecimal.ZERO;
                        }
                        saasUserTask.insert();
                        list.add(saasUserTask);
                    }
                }

                // 修改的同时不新增.并且也不完成任务
                if (NumberUtil.isLess(add, configurationCount)) {
                    bySaasTask.setSchedule(add);
                    bySaasTask.updateById();
                }

                // 修改本条为完成任务
                if (NumberUtil.equals(add, configurationCount)) {
                    if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                        return;
                    }
                    bySaasTask.setSchedule(add);
                    bySaasTask.setFulfilTime(DateUtil.date());
                    bySaasTask.setFulfilStatus(Boolean.TRUE);
                    bySaasTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                    TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                    bySaasTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                    bySaasTask.setSaasType(saasTask.getSaasType());
                    bySaasTask.setStageId(taskAwardIdAndStageId.getStageId());
                    bySaasTask.updateById();
                    list.add(bySaasTask);
                }
            }

        });
        addSaasTaskDrawPrize(list);
    }


    private void businessCardBuy(SaasTaskBurialPointDTO saasTaskBurialPointDTO) {
        List<SaasUserTask> byTaskTypeAndUserId = saasUserTaskDao.getByTaskTypeAndUserId(saasTaskBurialPointDTO.getTaskType(), saasTaskBurialPointDTO.getUserId());
        if (CollUtil.isNotEmpty(byTaskTypeAndUserId)) {
            log.info("该用户已经开通过名片,不需要做任何操作,参数:{}", JSON.toJSON(saasTaskBurialPointDTO));
            return;
        }
        List<SaasUserTask> list = new ArrayList<>();
        List<SaasTask> meetTheTask = saasTaskDao.getByTaskTypeAndValid(saasTaskBurialPointDTO.getTaskType(), saasTaskBurialPointDTO.getUserId());
        saasTaskBurialPointDTO.setValid(meetTheTask);
        meetTheTask.forEach(saasTask -> {
            if (saasTask.getTaskVisible().equals(SaasTaskVisibleEnum.DAO)) {
                // 如果这个任务是某个dao的任务的话,那么需要验证这个用户是否在这个dao的网体下.不是直接结束.
                if (!sublink(saasTask, saasTaskBurialPointDTO.getUserId())) {
                    return;
                }
            }

            // 任务可完成数量-1  如果任务可完成数量为0,那么就是不可完成的任务. 就不需要落库了.
            if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                return;
            }

            SaasUserTask saasUserTask = new SaasUserTask();
            saasUserTask.setSaasTaskId(saasTask.getId());
            saasUserTask.setAccomplishSum(1);
            saasUserTask.setTaskTrace(saasTask.getTaskTrace());
            saasUserTask.setUserId(saasTaskBurialPointDTO.getUserId());
            saasUserTask.setTaskType(saasTaskBurialPointDTO.getTaskType());
            saasUserTask.setSchedule(BigDecimal.ONE);
            saasUserTask.setVoluntarySum(0);
            saasUserTask.setStatus(Boolean.FALSE);
            // 需要根据任务的配置,给用户发放奖励.
            TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
            saasUserTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
            saasUserTask.setStageId(taskAwardIdAndStageId.getStageId());
            saasUserTask.setSaasType(saasTask.getSaasType());
            saasUserTask.setFulfilStatus(Boolean.TRUE);
            saasUserTask.setFulfilTime(DateUtil.date());
            saasUserTask.setOverTime(saasTask.getTaskEnd());
            saasUserTask.setSaasType(saasTask.getSaasType());
            list.add(saasUserTask);
        });
        saasUserTaskDao.saveBatch(list);
        addSaasTaskDrawPrize(list);
    }

    /**
     * 熔炼藏品
     *
     * @param saasTaskBurialPointDTO
     */
    @SneakyThrows
    public void meltingNftTotalConsumption(SaasTaskBurialPointDTO saasTaskBurialPointDTO) {
        //  获取符合条件的任务
        List<SaasTask> meetTheTask = saasTaskDao.getByTaskTypeAndValid(saasTaskBurialPointDTO.getTaskType(), saasTaskBurialPointDTO.getUserId());
        saasTaskBurialPointDTO.setValid(meetTheTask);
        // 获取任务的条件
        List<SaasUserTask> list = new ArrayList<>();
        meetTheTask.forEach(saasTask -> {

            if (saasTask.getTaskVisible().equals(SaasTaskVisibleEnum.DAO)) {
                // 如果这个任务是某个dao的任务的话,那么需要验证这个用户是否在这个dao的网体下.不是直接结束.
                if (!sublink(saasTask, saasTaskBurialPointDTO.getUserId())) {
                    return;
                }
            }
            // 根据任务的id获取任务的条件
            SaasTaskMeetConditions saasTaskMeetConditions = saasTaskMeetConditionsDao.getByTaskId(saasTask.getId());
            // 任务条件不满足
            if (BeanUtil.isEmpty(saasTaskMeetConditions)) {
                return;
            }

            // 根据任务的条件id获取任务的条件选项
            List<SaasTaskMeetConditionsOption> byTaskIdAndConditionId = saasTaskMeetConditionsOptionDao.getByTaskIdAndConditionId(saasTask.getId(),
                    saasTaskBurialPointDTO.getConditionId(), 2);
            // 任务条件购买是空的,也就是说,这个藏品不需要购买.
            if (CollUtil.isEmpty(byTaskIdAndConditionId)) {
                return;
            }

            /*
            用户购买的不是空的,证明用户购买是命中了的.并且他因为只要能查询出来的任务就可以去完成的.所以这里需要考虑到他的任务数量.
            1.考虑任务的剩余数量进度问题.要在修改的时候做判定.虽然查询出来的时候有大于0判定,但是要考虑事务以及并发的问题.所以一旦出现了数量不符就要回滚.
            2.考虑他超出的部分的问题,他有可能会出现有多条的情况.所以在修改原本的一条的时候,多余的部分 需要新生成多条.这个条目根据任务的配置来.
            * */
            SaasUserTask bySaasTask = saasUserTaskDao.getBySaasTask(saasTask.getId(), saasTaskBurialPointDTO.getUserId());
            if (BeanUtil.isEmpty(bySaasTask)) {
                // 当前没有执行中的任务,根据配置新增对应的份数,如果大于1的话,那么最后一份是未完成,其他的为已完成.如果为1的话则只完成一份 否则的话是未完成
                // 配置需要购买的数量
                BigDecimal configurationCount = saasTaskMeetConditions.getSchedule();
                // 用户购买的数量
                BigDecimal userBuyCount = saasTaskBurialPointDTO.getSchedule();
                // 用户购买数量大于配置的数量,那么就需要新增多份
                while (true) {
                    if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                        break;
                    }
                    SaasUserTask saasUserTask = new SaasUserTask();
                    saasUserTask.setSaasTaskId(saasTask.getId());
                    saasUserTask.setTaskTrace(saasTask.getTaskTrace());
                    saasUserTask.setUserId(saasTaskBurialPointDTO.getUserId());
                    saasUserTask.setTaskType(saasTaskBurialPointDTO.getTaskType());
                    if (NumberUtil.isLessOrEqual(userBuyCount, BigDecimal.ZERO)) {
                        break;
                    }
                    // 当购买数值比配置数值大的时候,就给直接完成的数据
                    if (NumberUtil.isGreater(userBuyCount, configurationCount)) {
                        // 任务数量是否足够
                        if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                            break;
                        }
                        saasUserTask.setSchedule(configurationCount);
                        saasUserTask.setVoluntarySum(0);
                        saasUserTask.setStatus(Boolean.FALSE);
                        saasUserTask.setFulfilStatus(Boolean.TRUE);
                        saasUserTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                        saasUserTask.setFulfilTime(DateUtil.date());
                        TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                        saasUserTask.setSaasType(saasTask.getSaasType());
                        saasUserTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                        saasUserTask.setStageId(taskAwardIdAndStageId.getStageId());
                        saasUserTask.setOverTime(DateUtil.offsetDay(saasTask.getTaskEnd(), 15));
                        // 自己的数据减去配置的数据,作为下一次循环的依据
                        userBuyCount = userBuyCount.subtract(configurationCount);
                    } else if (NumberUtil.equals(userBuyCount, configurationCount)) {
                        if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                            break;
                        }
                        saasUserTask.setSchedule(configurationCount);
                        saasUserTask.setVoluntarySum(0);
                        saasUserTask.setStatus(Boolean.FALSE);
                        saasUserTask.setFulfilStatus(Boolean.TRUE);
                        saasUserTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                        saasUserTask.setFulfilTime(DateUtil.date());
                        TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                        saasUserTask.setSaasType(saasTask.getSaasType());
                        saasUserTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                        saasUserTask.setStageId(taskAwardIdAndStageId.getStageId());
                        saasUserTask.setOverTime(DateUtil.offsetDay(saasTask.getTaskEnd(), 15));
                        userBuyCount = BigDecimal.ZERO;
                    } else {
                        // 否则就给未完成的数据
                        saasUserTask.setSchedule(userBuyCount);
                        saasUserTask.setFulfilStatus(Boolean.FALSE);
                        saasUserTask.setOverTime(DateUtil.offsetDay(saasTask.getTaskEnd(), 15));
                        saasUserTask.setSaasType(saasTask.getSaasType());
                        userBuyCount = BigDecimal.ZERO;
                    }
                    saasUserTask.insert();
                    list.add(saasUserTask);
                }
            } else {
                // 当存在任务的时候,则已经触发的任务加上这次的购买数量,如果大于配置的数量,那么就是完成的,否则就是未完成的,并且把多出来的部分生成一个新的任务
                // 配置
                BigDecimal configurationCount = saasTaskMeetConditions.getSchedule();
                BigDecimal add = bySaasTask.getSchedule().add(saasTaskBurialPointDTO.getSchedule());
                // 修改的同时,还要把多余的部分新增
                if (NumberUtil.isGreater(add, configurationCount)) {
                    if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                        return;
                    }
                    if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                        return;
                    }
                    bySaasTask.setSchedule(configurationCount);
                    bySaasTask.setFulfilTime(DateUtil.date());
                    bySaasTask.setFulfilStatus(Boolean.TRUE);
                    bySaasTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                    TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                    bySaasTask.setSaasType(saasTask.getSaasType());
                    bySaasTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                    bySaasTask.setStageId(taskAwardIdAndStageId.getStageId());

                    bySaasTask.updateById();
                    list.add(bySaasTask);
                    // 获取多余部分,用用户的额度+购买的额度-配置的额度就是剩余的额度
                    BigDecimal userBuyCount = add.subtract(configurationCount);
                    while (true) {
                        if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                            break;
                        }
                        SaasUserTask saasUserTask = new SaasUserTask();
                        saasUserTask.setSaasTaskId(saasTask.getId());
                        saasUserTask.setTaskTrace(saasTask.getTaskTrace());
                        saasUserTask.setUserId(saasTaskBurialPointDTO.getUserId());
                        saasUserTask.setTaskType(saasTaskBurialPointDTO.getTaskType());
                        if (NumberUtil.isLessOrEqual(userBuyCount, BigDecimal.ZERO)) {
                            break;
                        }
                        // 当购买数值比配置数值大的时候,就给直接完成的数据
                        if (NumberUtil.isGreater(userBuyCount, configurationCount)) {
                            saasUserTask.setSchedule(configurationCount);
                            saasUserTask.setVoluntarySum(0);
                            saasUserTask.setStatus(Boolean.FALSE);
                            saasUserTask.setFulfilStatus(Boolean.TRUE);
                            saasUserTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                            saasUserTask.setFulfilTime(DateUtil.date());
                            TaskAwardIdAndStageIdVO taskAwardIdAndStageIdResult = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                            saasUserTask.setSaasType(saasTask.getSaasType());
                            saasUserTask.setTaskAwardId(taskAwardIdAndStageIdResult.getAwardId());
                            saasUserTask.setStageId(taskAwardIdAndStageIdResult.getStageId());
                            saasUserTask.setOverTime(DateUtil.offsetDay(saasTask.getTaskEnd(), 15));
                            // 自己的数据减去配置的数据,作为下一次循环的依据
                            userBuyCount = userBuyCount.subtract(configurationCount);
                            if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                                break;
                            }
                        } else {
                            // 否则就给未完成的数据
                            saasUserTask.setSchedule(userBuyCount);
                            saasUserTask.setFulfilStatus(Boolean.FALSE);
                            saasUserTask.setOverTime(DateUtil.offsetDay(saasTask.getTaskEnd(), 15));
                            saasUserTask.setSaasType(saasTask.getSaasType());
                            userBuyCount = BigDecimal.ZERO;
                        }
                        saasUserTask.insert();
                        list.add(saasUserTask);
                    }
                }

                // 修改的同时不新增.并且也不完成任务
                if (NumberUtil.isLess(add, configurationCount)) {
                    bySaasTask.setSchedule(add);
                    bySaasTask.updateById();
                }

                // 修改本条为完成任务
                if (NumberUtil.equals(add, configurationCount)) {
                    if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                        return;
                    }
                    if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                        return;
                    }
                    bySaasTask.setSchedule(add);
                    bySaasTask.setFulfilTime(DateUtil.date());
                    bySaasTask.setFulfilStatus(Boolean.TRUE);
                    bySaasTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                    TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                    bySaasTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                    bySaasTask.setStageId(taskAwardIdAndStageId.getStageId());
                    bySaasTask.setSaasType(saasTask.getSaasType());
                    bySaasTask.updateById();
                    list.add(bySaasTask);
                }
            }
        });
        addSaasTaskDrawPrize(list);
    }

    /**
     * 分解藏品
     *
     * @param saasTaskBurialPointDTO
     */
    @SneakyThrows
    public void decomposeNftTotalConsumption(SaasTaskBurialPointDTO saasTaskBurialPointDTO) {
        //  获取符合条件的任务
        List<SaasTask> meetTheTask = saasTaskDao.getByTaskTypeAndValid(saasTaskBurialPointDTO.getTaskType(), saasTaskBurialPointDTO.getUserId());
        saasTaskBurialPointDTO.setValid(meetTheTask);
        // 获取任务的条件
        List<SaasUserTask> list = new ArrayList<>();
        meetTheTask.forEach(saasTask -> {
            if (saasTask.getTaskVisible().equals(SaasTaskVisibleEnum.DAO)) {
                // 如果这个任务是某个dao的任务的话,那么需要验证这个用户是否在这个dao的网体下.不是直接结束.
                if (!sublink(saasTask, saasTaskBurialPointDTO.getUserId())) {
                    return;
                }
            }
            // 根据任务的id获取任务的条件
            SaasTaskMeetConditions saasTaskMeetConditions = saasTaskMeetConditionsDao.getByTaskId(saasTask.getId());
            // 任务条件不满足
            if (BeanUtil.isEmpty(saasTaskMeetConditions)) {
                return;
            }

            // 根据任务的条件id获取任务的条件选项
            List<SaasTaskMeetConditionsOption> byTaskIdAndConditionId = saasTaskMeetConditionsOptionDao.getByTaskIdAndConditionId(saasTask.getId(), saasTaskBurialPointDTO.getConditionId(), 2);
            // 任务条件购买是空的,也就是说,这个藏品不需要购买.
            if (CollUtil.isEmpty(byTaskIdAndConditionId)) {
                return;
            }

            /*
            用户购买的不是空的,证明用户购买是命中了的.并且他因为只要能查询出来的任务就可以去完成的.所以这里需要考虑到他的任务数量.
            1.考虑任务的剩余数量进度问题.要在修改的时候做判定.虽然查询出来的时候有大于0判定,但是要考虑事务以及并发的问题.所以一旦出现了数量不符就要回滚.
            2.考虑他超出的部分的问题,他有可能会出现有多条的情况.所以在修改原本的一条的时候,多余的部分 需要新生成多条.这个条目根据任务的配置来.
            * */
            SaasUserTask bySaasTask = saasUserTaskDao.getBySaasTask(saasTask.getId(), saasTaskBurialPointDTO.getUserId());
            if (BeanUtil.isEmpty(bySaasTask)) {
                // 当前没有执行中的任务,根据配置新增对应的份数,如果大于1的话,那么最后一份是未完成,其他的为已完成.如果为1的话则只完成一份 否则的话是未完成
                // 配置需要购买的数量
                BigDecimal configurationCount = saasTaskMeetConditions.getSchedule();
                // 用户购买的数量
                BigDecimal userBuyCount = saasTaskBurialPointDTO.getSchedule();
                // 用户购买数量大于配置的数量,那么就需要新增多份
                while (true) {
                    if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                        break;
                    }
                    SaasUserTask saasUserTask = new SaasUserTask();
                    saasUserTask.setSaasTaskId(saasTask.getId());
                    saasUserTask.setTaskTrace(saasTask.getTaskTrace());
                    saasUserTask.setUserId(saasTaskBurialPointDTO.getUserId());
                    saasUserTask.setTaskType(saasTaskBurialPointDTO.getTaskType());
                    if (NumberUtil.isLessOrEqual(userBuyCount, BigDecimal.ZERO)) {
                        break;
                    }
                    // 当购买数值比配置数值大的时候,就给直接完成的数据
                    if (NumberUtil.isGreater(userBuyCount, configurationCount)) {
                        // 任务数量是否足够
                        if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                            break;
                        }
                        saasUserTask.setSchedule(configurationCount);
                        saasUserTask.setVoluntarySum(0);
                        saasUserTask.setStatus(Boolean.FALSE);
                        saasUserTask.setFulfilStatus(Boolean.TRUE);
                        saasUserTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                        saasUserTask.setFulfilTime(DateUtil.date());
                        TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                        saasUserTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                        saasUserTask.setSaasType(saasTask.getSaasType());
                        saasUserTask.setStageId(taskAwardIdAndStageId.getStageId());

                        saasUserTask.setOverTime(DateUtil.offsetDay(saasTask.getTaskEnd(), 15));
                        // 自己的数据减去配置的数据,作为下一次循环的依据
                        userBuyCount = userBuyCount.subtract(configurationCount);
                    } else if (NumberUtil.equals(userBuyCount, configurationCount)) {
                        if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                            break;
                        }
                        saasUserTask.setSchedule(configurationCount);
                        saasUserTask.setVoluntarySum(0);
                        saasUserTask.setStatus(Boolean.FALSE);
                        saasUserTask.setFulfilStatus(Boolean.TRUE);
                        saasUserTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                        saasUserTask.setFulfilTime(DateUtil.date());
                        TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                        saasUserTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                        saasUserTask.setSaasType(saasTask.getSaasType());
                        saasUserTask.setStageId(taskAwardIdAndStageId.getStageId());

                        saasUserTask.setOverTime(DateUtil.offsetDay(saasTask.getTaskEnd(), 15));
                        userBuyCount = BigDecimal.ZERO;
                    } else {
                        // 否则就给未完成的数据
                        saasUserTask.setSchedule(userBuyCount);
                        saasUserTask.setFulfilStatus(Boolean.FALSE);
                        saasUserTask.setOverTime(DateUtil.offsetDay(saasTask.getTaskEnd(), 15));
                        saasUserTask.setSaasType(saasTask.getSaasType());
                        userBuyCount = BigDecimal.ZERO;
                    }
                    saasUserTask.insert();
                    list.add(saasUserTask);
                }
            } else {
                // 当存在任务的时候,则已经触发的任务加上这次的购买数量,如果大于配置的数量,那么就是完成的,否则就是未完成的,并且把多出来的部分生成一个新的任务
                // 配置
                BigDecimal configurationCount = saasTaskMeetConditions.getSchedule();
                BigDecimal add = bySaasTask.getSchedule().add(saasTaskBurialPointDTO.getSchedule());
                // 修改的同时,还要把多余的部分新增
                if (NumberUtil.isGreater(add, configurationCount)) {
                    if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                        return;
                    }
                    if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                        return;
                    }
                    bySaasTask.setSchedule(configurationCount);
                    bySaasTask.setFulfilTime(DateUtil.date());
                    bySaasTask.setFulfilStatus(Boolean.TRUE);
                    bySaasTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                    TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                    bySaasTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                    bySaasTask.setSaasType(saasTask.getSaasType());
                    bySaasTask.setStageId(taskAwardIdAndStageId.getStageId());

                    bySaasTask.updateById();
                    list.add(bySaasTask);
                    // 获取多余部分,用用户的额度+购买的额度-配置的额度就是剩余的额度
                    BigDecimal userBuyCount = add.subtract(configurationCount);
                    while (true) {
                        if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                            break;
                        }
                        SaasUserTask saasUserTask = new SaasUserTask();
                        saasUserTask.setSaasTaskId(saasTask.getId());
                        saasUserTask.setTaskTrace(saasTask.getTaskTrace());
                        saasUserTask.setUserId(saasTaskBurialPointDTO.getUserId());
                        saasUserTask.setTaskType(saasTaskBurialPointDTO.getTaskType());
                        if (NumberUtil.isLessOrEqual(userBuyCount, BigDecimal.ZERO)) {
                            break;
                        }
                        // 当购买数值比配置数值大的时候,就给直接完成的数据
                        if (NumberUtil.isGreater(userBuyCount, configurationCount)) {
                            saasUserTask.setSchedule(configurationCount);
                            saasUserTask.setVoluntarySum(0);
                            saasUserTask.setStatus(Boolean.FALSE);
                            saasUserTask.setFulfilStatus(Boolean.TRUE);
                            saasUserTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                            saasUserTask.setFulfilTime(DateUtil.date());
                            TaskAwardIdAndStageIdVO taskAwardIdAndStageIdResult = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                            saasUserTask.setTaskAwardId(taskAwardIdAndStageIdResult.getAwardId());
                            saasUserTask.setSaasType(saasTask.getSaasType());
                            saasUserTask.setStageId(taskAwardIdAndStageIdResult.getStageId());

                            saasUserTask.setOverTime(DateUtil.offsetDay(saasTask.getTaskEnd(), 15));
                            // 自己的数据减去配置的数据,作为下一次循环的依据
                            userBuyCount = userBuyCount.subtract(configurationCount);
                            if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                                break;
                            }
                        } else {
                            // 否则就给未完成的数据
                            saasUserTask.setSchedule(userBuyCount);
                            saasUserTask.setFulfilStatus(Boolean.FALSE);
                            saasUserTask.setOverTime(DateUtil.offsetDay(saasTask.getTaskEnd(), 15));
                            saasUserTask.setSaasType(saasTask.getSaasType());
                            userBuyCount = BigDecimal.ZERO;
                        }
                        saasUserTask.insert();
                        list.add(saasUserTask);
                    }
                }

                // 修改的同时不新增.并且也不完成任务
                if (NumberUtil.isLess(add, configurationCount)) {
                    bySaasTask.setSchedule(add);
                    bySaasTask.updateById();
                }

                // 修改本条为完成任务
                if (NumberUtil.equals(add, configurationCount)) {
                    if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                        return;
                    }
                    if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                        return;
                    }
                    bySaasTask.setSchedule(add);
                    bySaasTask.setFulfilTime(DateUtil.date());
                    bySaasTask.setFulfilStatus(Boolean.TRUE);
                    bySaasTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                    TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                    bySaasTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                    bySaasTask.setSaasType(saasTask.getSaasType());
                    bySaasTask.setStageId(taskAwardIdAndStageId.getStageId());

                    bySaasTask.updateById();
                    list.add(bySaasTask);
                }
            }
        });
        addSaasTaskDrawPrize(list);
    }


    /**
     * 合成藏品
     *
     * @param saasTaskBurialPointDTO
     */
    @SneakyThrows
    public void  compoundNftTotalConsumption(SaasTaskBurialPointDTO saasTaskBurialPointDTO) {
        //  获取符合条件的任务
        List<SaasTask> meetTheTask = saasTaskDao.getByTaskTypeAndValid(saasTaskBurialPointDTO.getTaskType(), saasTaskBurialPointDTO.getUserId());
        log.info("合成藏品任务:{}", meetTheTask);
        saasTaskBurialPointDTO.setValid(meetTheTask);
        // 获取任务的条件
        List<SaasUserTask> list = new ArrayList<>();
        meetTheTask.forEach(saasTask -> {
            if (saasTask.getTaskVisible().equals(SaasTaskVisibleEnum.DAO)) {
                // 如果这个任务是某个dao的任务的话,那么需要验证这个用户是否在这个dao的网体下.不是直接结束.
                if (!sublink(saasTask, saasTaskBurialPointDTO.getUserId())) {
                    return;
                }
            }
            log.info("合成藏品任务DAO判断过了.");
            // 根据任务的id获取任务的条件
            SaasTaskMeetConditions saasTaskMeetConditions = saasTaskMeetConditionsDao.getByTaskId(saasTask.getId());
            // 任务条件不满足
            if (BeanUtil.isEmpty(saasTaskMeetConditions)) {
                return;
            }
            log.info("判定条件过了");
            // 根据任务的条件id获取任务的条件选项
            List<SaasTaskMeetConditionsOption> byTaskIdAndConditionId = saasTaskMeetConditionsOptionDao.getByTaskIdAndConditionId(saasTask.getId(), saasTaskBurialPointDTO.getConditionId(), 2);
            log.info("任务条件结果:{}",JSON.toJSON(byTaskIdAndConditionId));
            log.info("任务条件请求参数:{}-{}",saasTask.getId(), saasTaskBurialPointDTO.getConditionId());
            // 任务条件购买是空的,也就是说,这个藏品不需要购买.
            if (CollUtil.isEmpty(byTaskIdAndConditionId)) {
                return;
            }
            log.info("任务条件过了");
            // 要考虑用户购买条件和持有条件相同的情况,如果用户购买的藏品和持有的藏品相同,那么先就看用户买的数量和持有数量是否相等,如果持有数量>购买数量 则代表他之前有持有
            List<SaasTaskMeetConditionsOption> isHoldCollection = saasTaskMeetConditionsOptionDao.getByTaskIdAndConditionId(saasTask.getId(), saasTaskBurialPointDTO.getConditionId(), 1);
            if (!CollUtil.isEmpty(isHoldCollection)) {
                // 验证用户的持有数量和完成数量是否一致
                Integer countByCollercitonIdAndUserId = userCollectionDao.getCountByCollercitonIdAndUserId(saasTaskBurialPointDTO.getUserId(), saasTaskBurialPointDTO.getConditionId());
                if (NumberUtil.isLessOrEqual(Convert.toBigDecimal(countByCollercitonIdAndUserId), saasTaskBurialPointDTO.getSchedule())) {
                    return;
                }
            }
            log.info("任务的持有过了");
            /*
            用户购买的不是空的,证明用户购买是命中了的.并且他因为只要能查询出来的任务就可以去完成的.所以这里需要考虑到他的任务数量.
            1.考虑任务的剩余数量进度问题.要在修改的时候做判定.虽然查询出来的时候有大于0判定,但是要考虑事务以及并发的问题.所以一旦出现了数量不符就要回滚.
            2.考虑他超出的部分的问题,他有可能会出现有多条的情况.所以在修改原本的一条的时候,多余的部分 需要新生成多条.这个条目根据任务的配置来.
            * */
            log.info("开始计算任务奖励");
            SaasUserTask bySaasTask = saasUserTaskDao.getBySaasTask(saasTask.getId(), saasTaskBurialPointDTO.getUserId());
            if (BeanUtil.isEmpty(bySaasTask)) {
                log.info("奖励为空");
                // 当前没有执行中的任务,根据配置新增对应的份数,如果大于1的话,那么最后一份是未完成,其他的为已完成.如果为1的话则只完成一份 否则的话是未完成
                // 配置需要购买的数量
                BigDecimal configurationCount = saasTaskMeetConditions.getSchedule();
                // 用户购买的数量
                BigDecimal userBuyCount = saasTaskBurialPointDTO.getSchedule();
                // 用户购买数量大于配置的数量,那么就需要新增多份
                while (true) {
                    if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                        break;
                    }
                    SaasUserTask saasUserTask = new SaasUserTask();
                    saasUserTask.setSaasTaskId(saasTask.getId());
                    saasUserTask.setTaskTrace(saasTask.getTaskTrace());
                    saasUserTask.setUserId(saasTaskBurialPointDTO.getUserId());
                    saasUserTask.setTaskType(saasTaskBurialPointDTO.getTaskType());
                    if (NumberUtil.isLessOrEqual(userBuyCount, BigDecimal.ZERO)) {
                        break;
                    }
                    // 当购买数值比配置数值大的时候,就给直接完成的数据
                    if (NumberUtil.isGreater(userBuyCount, configurationCount)) {
                        // 任务数量是否足够
                        if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                            break;
                        }
                        saasUserTask.setSchedule(configurationCount);
                        saasUserTask.setVoluntarySum(0);
                        saasUserTask.setStatus(Boolean.FALSE);
                        saasUserTask.setFulfilStatus(Boolean.TRUE);
                        saasUserTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                        saasUserTask.setFulfilTime(DateUtil.date());
                        TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                        saasUserTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                        saasUserTask.setSaasType(saasTask.getSaasType());
                        saasUserTask.setStageId(taskAwardIdAndStageId.getStageId());
                        saasUserTask.setOverTime(saasTask.getTaskEnd());
                        // 自己的数据减去配置的数据,作为下一次循环的依据
                        userBuyCount = userBuyCount.subtract(configurationCount);
                    } else if (NumberUtil.equals(userBuyCount, configurationCount)) {
                        if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                            break;
                        }
                        saasUserTask.setSchedule(configurationCount);
                        saasUserTask.setVoluntarySum(0);
                        saasUserTask.setStatus(Boolean.FALSE);
                        saasUserTask.setFulfilStatus(Boolean.TRUE);
                        saasUserTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                        saasUserTask.setFulfilTime(DateUtil.date());
                        TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                        log.info("奖励发放");
                        saasUserTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                        saasUserTask.setSaasType(saasTask.getSaasType());
                        saasUserTask.setStageId(taskAwardIdAndStageId.getStageId());
                        saasUserTask.setOverTime(saasTask.getTaskEnd());
                        userBuyCount = BigDecimal.ZERO;
                    } else {
                        // 否则就给未完成的数据
                        saasUserTask.setSchedule(userBuyCount);
                        saasUserTask.setFulfilStatus(Boolean.FALSE);
                        saasUserTask.setOverTime(saasTask.getTaskEnd());
                        saasUserTask.setSaasType(saasTask.getSaasType());
                        userBuyCount = BigDecimal.ZERO;
                    }
                    saasUserTask.insert();
                    log.info("新增数据奖励");
                    list.add(saasUserTask);
                }
            } else {
                // 当存在任务的时候,则已经触发的任务加上这次的购买数量,如果大于配置的数量,那么就是完成的,否则就是未完成的,并且把多出来的部分生成一个新的任务
                // 配置
                BigDecimal configurationCount = saasTaskMeetConditions.getSchedule();
                BigDecimal add = bySaasTask.getSchedule().add(saasTaskBurialPointDTO.getSchedule());
                // 修改的同时,还要把多余的部分新增
                if (NumberUtil.isGreater(add, configurationCount)) {
                    if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                        return;
                    }
                    if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                        return;
                    }
                    bySaasTask.setSchedule(configurationCount);
                    bySaasTask.setFulfilTime(DateUtil.date());
                    bySaasTask.setFulfilStatus(Boolean.TRUE);
                    bySaasTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                    TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                    bySaasTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                    bySaasTask.setSaasType(saasTask.getSaasType());
                    bySaasTask.setStageId(taskAwardIdAndStageId.getStageId());
                    bySaasTask.updateById();
                    list.add(bySaasTask);
                    // 获取多余部分,用用户的额度+购买的额度-配置的额度就是剩余的额度
                    BigDecimal userBuyCount = add.subtract(configurationCount);
                    while (true) {
                        if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                            break;
                        }
                        SaasUserTask saasUserTask = new SaasUserTask();
                        saasUserTask.setSaasTaskId(saasTask.getId());
                        saasUserTask.setTaskTrace(saasTask.getTaskTrace());
                        saasUserTask.setUserId(saasTaskBurialPointDTO.getUserId());
                        saasUserTask.setTaskType(saasTaskBurialPointDTO.getTaskType());
                        if (NumberUtil.isLessOrEqual(userBuyCount, BigDecimal.ZERO)) {
                            break;
                        }
                        // 当购买数值比配置数值大的时候,就给直接完成的数据
                        if (NumberUtil.isGreater(userBuyCount, configurationCount)) {
                            saasUserTask.setSchedule(configurationCount);
                            saasUserTask.setVoluntarySum(0);
                            saasUserTask.setStatus(Boolean.FALSE);
                            saasUserTask.setFulfilStatus(Boolean.TRUE);
                            saasUserTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                            saasUserTask.setFulfilTime(DateUtil.date());
                            TaskAwardIdAndStageIdVO taskAwardIdAndStageIdResult = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                            saasUserTask.setTaskAwardId(taskAwardIdAndStageIdResult.getAwardId());
                            saasUserTask.setSaasType(saasTask.getSaasType());
                            saasUserTask.setStageId(taskAwardIdAndStageIdResult.getStageId());
                            saasUserTask.setOverTime(DateUtil.offsetDay(saasTask.getTaskEnd(), 15));
                            // 自己的数据减去配置的数据,作为下一次循环的依据
                            userBuyCount = userBuyCount.subtract(configurationCount);
                            if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                                break;
                            }
                        } else {
                            // 否则就给未完成的数据
                            saasUserTask.setSchedule(userBuyCount);
                            saasUserTask.setFulfilStatus(Boolean.FALSE);
                            saasUserTask.setOverTime(saasTask.getTaskEnd());
                            saasUserTask.setSaasType(saasTask.getSaasType());
                            userBuyCount = BigDecimal.ZERO;
                        }
                        saasUserTask.insert();
                        log.info("新增数据奖励");
                        list.add(saasUserTask);
                    }
                }

                // 修改的同时不新增.并且也不完成任务
                if (NumberUtil.isLess(add, configurationCount)) {
                    bySaasTask.setSchedule(add);
                    bySaasTask.updateById();
                }

                // 修改本条为完成任务
                if (NumberUtil.equals(add, configurationCount)) {
                    if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                        return;
                    }
                    if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                        return;
                    }
                    bySaasTask.setSchedule(add);
                    bySaasTask.setFulfilTime(DateUtil.date());
                    bySaasTask.setFulfilStatus(Boolean.TRUE);
                    bySaasTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                    TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                    bySaasTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                    bySaasTask.setSaasType(saasTask.getSaasType());
                    bySaasTask.setStageId(taskAwardIdAndStageId.getStageId());

                    bySaasTask.updateById();
                    log.info("新增数据修改");
                    list.add(bySaasTask);
                }
            }
        });
        addSaasTaskDrawPrize(list);
    }

    /**
     * 根据条件范围累加金额
     *
     * @param saasTaskBurialPointDTO
     */
    @SneakyThrows
    public void userTotalConsumption(SaasTaskBurialPointDTO saasTaskBurialPointDTO) {
        //  获取符合条件的任务
        List<SaasTask> meetTheTask = saasTaskDao.getByTaskTypeAndValid(saasTaskBurialPointDTO.getTaskType(), saasTaskBurialPointDTO.getUserId());
        saasTaskBurialPointDTO.setValid(meetTheTask);
        // 获取任务的条件
        List<SaasUserTask> list = new ArrayList<>();
        meetTheTask.forEach(saasTask -> {
            Long taskId = saasTask.getId();
            SaasTaskMeetConditions taskMeetConditions = saasTaskMeetConditionsDao.getByTaskId(taskId);
            if (!taskMeetConditions.getTaskType().equals(SaasTaskTypeEnum.ACCUMULATED_CONSUMPTION_AMOUNT)) {
                return;
            }

            // 当任务是商城的时候，则判定他当前的时间是否为累计消费的金额，否则的话不进行处理

            if (saasTaskBurialPointDTO.getSaasTaskMeetConditionsLocationEnum()==SaasTaskMeetConditionsLocationEnum.MALL) {
                // 查询这个订单的付款时间，是否在大于任务开始时间以及小于任务结束时间,不在时间内命中的,都不允许完成任务,如果在时间内命中的则可以完成.
                MallOrder mallOrder = mallOrderDao.getById(saasTaskBurialPointDTO.getOrderId());
                if (!(mallOrder.getPayTime().after(saasTask.getTaskStart()) && mallOrder.getPayTime().before(saasTask.getTaskEnd()))) {
                    return;
                }
                // 要确定当前的这个购买的商品,是否是被排除的
                MallOrderProduct mallOrderProduct= mallOrderProductDao.getByOrderId(saasTaskBurialPointDTO.getOrderId());
                if (BeanUtil.isEmpty(mallOrderProduct)) {
                    return;
                }
                // 判定当前的商品的id,是否在对应的任务中的排除选里面.如果确定在的话.那么就不进行处理
                if (saasExcludeDao.existTaskIdAndProductId(taskId, mallOrderProduct.getProductId())) {
                    return;
                }
            }

            // 当累消是藏品的时候判定支付时间是否在活动区间内,因为获取的sql中往后延迟了15天,所以会拿出来.导致活动多了15天的奖励.
            if (saasTaskBurialPointDTO.getSaasTaskMeetConditionsLocationEnum()==SaasTaskMeetConditionsLocationEnum.COLLECTION) {
                // 查询这个订单的付款时间，是否在大于任务开始时间以及小于任务结束时间,不在时间内命中的,都不允许完成任务,如果在时间内命中的则可以完成.
                Order order = orderDao.getById(saasTaskBurialPointDTO.getOrderId());
                if (!(order.getPayTime().after(saasTask.getTaskStart()) && order.getPayTime().before(saasTask.getTaskEnd()))) {
                    return;
                }
            }

            SaasTaskMeetConditionsLocation taskAndLocation = saasTaskMeetConditionsLocationDao.getByTaskAndLocation(saasTaskBurialPointDTO
                    .getSaasTaskMeetConditionsLocationEnum(), saasTask.getId());
            if (Objects.isNull(taskAndLocation)) {
                return;
            }

            if (saasTask.getTaskVisible().equals(SaasTaskVisibleEnum.DAO)) {
                // 如果这个任务是某个dao的任务的话,那么需要验证这个用户是否在这个dao的网体下.不是直接结束.
                if (!sublink(saasTask, saasTaskBurialPointDTO.getUserId())) {
                    return;
                }
            }
            // 根据任务的id获取任务的条件
            SaasTaskMeetConditions saasTaskMeetConditions = saasTaskMeetConditionsDao.getByTaskId(saasTask.getId());
            // 任务条件不满足
            if (BeanUtil.isEmpty(saasTaskMeetConditions)) {
                return;
            }

            /*
            用户购买的不是空的,证明用户购买是命中了的.并且他因为只要能查询出来的任务就可以去完成的.所以这里需要考虑到他的任务数量.
            1.考虑任务的剩余数量进度问题.要在修改的时候做判定.虽然查询出来的时候有大于0判定,但是要考虑事务以及并发的问题.所以一旦出现了数量不符就要回滚.
            2.考虑他超出的部分的问题,他有可能会出现有多条的情况.所以在修改原本的一条的时候,多余的部分 需要新生成多条.这个条目根据任务的配置来.
            * */
            SaasUserTask bySaasTask = saasUserTaskDao.getBySaasTask(saasTask.getId(), saasTaskBurialPointDTO.getUserId());
            if (BeanUtil.isEmpty(bySaasTask)) {
                // 当前没有执行中的任务,根据配置新增对应的份数,如果大于1的话,那么最后一份是未完成,其他的为已完成.如果为1的话则只完成一份 否则的话是未完成
                // 配置需要购买的数量
                BigDecimal configurationCount = saasTaskMeetConditions.getSchedule();
                // 用户购买的数量
                BigDecimal userBuyCount = saasTaskBurialPointDTO.getSchedule();
                // 用户购买数量大于配置的数量,那么就需要新增多份
                while (true) {
                    if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                        break;
                    }
                    SaasUserTask saasUserTask = new SaasUserTask();
                    saasUserTask.setSaasTaskId(saasTask.getId());
                    saasUserTask.setTaskTrace(saasTask.getTaskTrace());
                    saasUserTask.setUserId(saasTaskBurialPointDTO.getUserId());
                    saasUserTask.setTaskType(saasTaskBurialPointDTO.getTaskType());
                    if (NumberUtil.isLessOrEqual(userBuyCount, BigDecimal.ZERO)) {
                        break;
                    }
                    // 当购买数值比配置数值大的时候,就给直接完成的数据
                    if (NumberUtil.isGreater(userBuyCount, configurationCount)) {
                        // 任务数量是否足够
                        if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                            break;
                        }
                        saasUserTask.setSchedule(configurationCount);
                        saasUserTask.setVoluntarySum(0);
                        saasUserTask.setStatus(Boolean.FALSE);
                        saasUserTask.setFulfilStatus(Boolean.TRUE);
                        saasUserTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                        saasUserTask.setFulfilTime(DateUtil.date());
                        TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                        saasUserTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                        saasUserTask.setSaasType(saasTask.getSaasType());
                        saasUserTask.setStageId(taskAwardIdAndStageId.getStageId());
                        saasUserTask.setOverTime(DateUtil.offsetDay(saasTask.getTaskEnd(), 15));
                        // 自己的数据减去配置的数据,作为下一次循环的依据
                        userBuyCount = userBuyCount.subtract(configurationCount);
                    } else if (NumberUtil.equals(userBuyCount, configurationCount)) {
                        if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                            break;
                        }
                        saasUserTask.setSchedule(configurationCount);
                        saasUserTask.setVoluntarySum(0);
                        saasUserTask.setStatus(Boolean.FALSE);
                        saasUserTask.setFulfilStatus(Boolean.TRUE);
                        saasUserTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                        saasUserTask.setFulfilTime(DateUtil.date());
                        TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                        saasUserTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                        saasUserTask.setSaasType(saasTask.getSaasType());
                        saasUserTask.setStageId(taskAwardIdAndStageId.getStageId());
                        saasUserTask.setOverTime(DateUtil.offsetDay(saasTask.getTaskEnd(), 15));
                        userBuyCount = BigDecimal.ZERO;
                    } else {
                        // 否则就给未完成的数据
                        saasUserTask.setSchedule(userBuyCount);
                        saasUserTask.setFulfilStatus(Boolean.FALSE);
                        saasUserTask.setOverTime(DateUtil.offsetDay(saasTask.getTaskEnd(), 15));
                        saasUserTask.setSaasType(saasTask.getSaasType());
                        userBuyCount = BigDecimal.ZERO;
                    }
                    saasUserTask.insert();
                    list.add(saasUserTask);
                }
            } else {
                // 当存在任务的时候,则已经触发的任务加上这次的购买数量,如果大于配置的数量,那么就是完成的,否则就是未完成的,并且把多出来的部分生成一个新的任务
                // 配置
                BigDecimal configurationCount = saasTaskMeetConditions.getSchedule();
                BigDecimal add = bySaasTask.getSchedule().add(saasTaskBurialPointDTO.getSchedule());
                // 修改的同时,还要把多余的部分新增
                if (NumberUtil.isGreater(add, configurationCount)) {
                    if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                        return;
                    }
                    if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                        return;
                    }
                    bySaasTask.setSchedule(configurationCount);
                    bySaasTask.setFulfilTime(DateUtil.date());
                    bySaasTask.setFulfilStatus(Boolean.TRUE);
                    bySaasTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                    TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                    bySaasTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                    bySaasTask.setSaasType(saasTask.getSaasType());
                    bySaasTask.setStageId(taskAwardIdAndStageId.getStageId());
                    bySaasTask.updateById();
                    list.add(bySaasTask);
                    // 获取多余部分,用用户的额度+购买的额度-配置的额度就是剩余的额度
                    BigDecimal userBuyCount = add.subtract(configurationCount);
                    while (true) {
                        if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                            break;
                        }
                        SaasUserTask saasUserTask = new SaasUserTask();
                        saasUserTask.setSaasTaskId(saasTask.getId());
                        saasUserTask.setTaskTrace(saasTask.getTaskTrace());
                        saasUserTask.setUserId(saasTaskBurialPointDTO.getUserId());
                        saasUserTask.setTaskType(saasTaskBurialPointDTO.getTaskType());
                        if (NumberUtil.isLessOrEqual(userBuyCount, BigDecimal.ZERO)) {
                            break;
                        }
                        // 当购买数值比配置数值大的时候,就给直接完成的数据
                        if (NumberUtil.isGreater(userBuyCount, configurationCount)) {
                            saasUserTask.setSchedule(configurationCount);
                            saasUserTask.setVoluntarySum(0);
                            saasUserTask.setStatus(Boolean.FALSE);
                            saasUserTask.setFulfilStatus(Boolean.TRUE);
                            saasUserTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                            saasUserTask.setFulfilTime(DateUtil.date());
                            TaskAwardIdAndStageIdVO taskAwardIdAndStageIdResult = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                            saasUserTask.setTaskAwardId(taskAwardIdAndStageIdResult.getAwardId());
                            saasUserTask.setStageId(taskAwardIdAndStageIdResult.getStageId());
                            saasUserTask.setSaasType(saasTask.getSaasType());
                            saasUserTask.setOverTime(DateUtil.offsetDay(saasTask.getTaskEnd(), 15));
                            // 自己的数据减去配置的数据,作为下一次循环的依据
                            userBuyCount = userBuyCount.subtract(configurationCount);
                            if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                                break;
                            }
                        } else {
                            // 否则就给未完成的数据
                            saasUserTask.setSchedule(userBuyCount);
                            saasUserTask.setFulfilStatus(Boolean.FALSE);
                            saasUserTask.setOverTime(DateUtil.offsetDay(saasTask.getTaskEnd(), 15));
                            saasUserTask.setSaasType(saasTask.getSaasType());
                            userBuyCount = BigDecimal.ZERO;
                        }
                        saasUserTask.insert();
                        list.add(saasUserTask);
                    }
                }

                // 修改的同时不新增.并且也不完成任务
                if (NumberUtil.isLess(add, configurationCount)) {
                    bySaasTask.setSchedule(add);
                    bySaasTask.updateById();
                }

                // 修改本条为完成任务
                if (NumberUtil.equals(add, configurationCount)) {
                    if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                        return;
                    }
                    if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                        return;
                    }
                    bySaasTask.setSchedule(add);
                    bySaasTask.setFulfilTime(DateUtil.date());
                    bySaasTask.setFulfilStatus(Boolean.TRUE);
                    bySaasTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                    TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                    bySaasTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                    bySaasTask.setSaasType(saasTask.getSaasType());
                    bySaasTask.setStageId(taskAwardIdAndStageId.getStageId());
                    bySaasTask.updateById();
                    list.add(bySaasTask);
                }
            }
        });
        addSaasTaskDrawPrize(list);
    }


    /**
     * CDK兑换
     *
     * @param saasTaskBurialPointDTO
     */
    @SneakyThrows
    public void cdkExchangeTotalConsumption(SaasTaskBurialPointDTO saasTaskBurialPointDTO) {
        //  获取符合条件的任务
        List<SaasTask> meetTheTask = saasTaskDao.getByTaskTypeAndValid(saasTaskBurialPointDTO.getTaskType(), saasTaskBurialPointDTO.getUserId());
        saasTaskBurialPointDTO.setValid(meetTheTask);
        // 获取任务的条件
        List<SaasUserTask> list = new ArrayList<>();
        meetTheTask.forEach(saasTask -> {
            // 查询这个订单的付款时间，是否在大于任务开始时间以及小于任务结束时间,不在时间内命中的,都不允许完成任务,如果在时间内命中的则可以完成.
            if (saasTask.getTaskVisible().equals(SaasTaskVisibleEnum.DAO)) {
                // 如果这个任务是某个dao的任务的话,那么需要验证这个用户是否在这个dao的网体下.不是直接结束.
                if (!sublink(saasTask, saasTaskBurialPointDTO.getUserId())) {
                    return;
                }
            }
            // 根据任务的id获取任务的条件
            SaasTaskMeetConditions saasTaskMeetConditions = saasTaskMeetConditionsDao.getByTaskId(saasTask.getId());
            // 任务条件不满足
            if (BeanUtil.isEmpty(saasTaskMeetConditions)) {
                return;
            }
            // 根据任务的条件id获取任务的条件选项
            List<SaasTaskMeetConditionsOption> byTaskIdAndConditionId = saasTaskMeetConditionsOptionDao.getByTaskIdAndConditionId(saasTask.getId(), saasTaskBurialPointDTO.getConditionId(), 2);
            // 任务条件购买是空的,也就是说,这个藏品不需要购买.
            if (CollUtil.isEmpty(byTaskIdAndConditionId)) {
                return;
            }
            // 要考虑用户购买条件和持有条件相同的情况,如果用户购买的藏品和持有的藏品相同,那么先就看用户买的数量和持有数量是否相等,如果持有数量>购买数量 则代表他之前有持有
            List<SaasTaskMeetConditionsOption> isHoldCollection = saasTaskMeetConditionsOptionDao.getByTaskIdAndConditionId(saasTask.getId(), saasTaskBurialPointDTO.getConditionId(), 1);
            if (!CollUtil.isEmpty(isHoldCollection)) {
                // 验证用户的持有数量和完成数量是否一致
                Integer countByCollercitonIdAndUserId = userCollectionDao.getCountByCollercitonIdAndUserId(saasTaskBurialPointDTO.getUserId(), saasTaskBurialPointDTO.getConditionId());
                if (NumberUtil.isLessOrEqual(Convert.toBigDecimal(countByCollercitonIdAndUserId), saasTaskBurialPointDTO.getSchedule())) {
                    return;
                }
            }
            /*
            用户购买的不是空的,证明用户购买是命中了的.并且他因为只要能查询出来的任务就可以去完成的.所以这里需要考虑到他的任务数量.
            1.考虑任务的剩余数量进度问题.要在修改的时候做判定.虽然查询出来的时候有大于0判定,但是要考虑事务以及并发的问题.所以一旦出现了数量不符就要回滚.
            2.考虑他超出的部分的问题,他有可能会出现有多条的情况.所以在修改原本的一条的时候,多余的部分 需要新生成多条.这个条目根据任务的配置来.
            * */
            SaasUserTask bySaasTask = saasUserTaskDao.getBySaasTask(saasTask.getId(), saasTaskBurialPointDTO.getUserId());
            if (BeanUtil.isEmpty(bySaasTask)) {
                // 当前没有执行中的任务,根据配置新增对应的份数,如果大于1的话,那么最后一份是未完成,其他的为已完成.如果为1的话则只完成一份 否则的话是未完成
                // 配置需要购买的数量
                BigDecimal configurationCount = saasTaskMeetConditions.getSchedule();
                // 用户购买的数量
                BigDecimal userBuyCount = saasTaskBurialPointDTO.getSchedule();
                // 用户购买数量大于配置的数量,那么就需要新增多份
                while (true) {
                    if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                        break;
                    }
                    SaasUserTask saasUserTask = new SaasUserTask();
                    saasUserTask.setSaasTaskId(saasTask.getId());
                    saasUserTask.setTaskTrace(saasTask.getTaskTrace());
                    saasUserTask.setUserId(saasTaskBurialPointDTO.getUserId());
                    saasUserTask.setTaskType(saasTaskBurialPointDTO.getTaskType());
                    if (NumberUtil.isLessOrEqual(userBuyCount, BigDecimal.ZERO)) {
                        break;
                    }
                    // 当购买数值比配置数值大的时候,就给直接完成的数据
                    if (NumberUtil.isGreater(userBuyCount, configurationCount)) {
                        // 任务数量是否足够
                        if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                            break;
                        }
                        saasUserTask.setSchedule(configurationCount);
                        saasUserTask.setVoluntarySum(0);
                        saasUserTask.setStatus(Boolean.FALSE);
                        saasUserTask.setFulfilStatus(Boolean.TRUE);
                        saasUserTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                        saasUserTask.setFulfilTime(DateUtil.date());
                        TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                        saasUserTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                        saasUserTask.setSaasType(saasTask.getSaasType());
                        saasUserTask.setStageId(taskAwardIdAndStageId.getStageId());

                        saasUserTask.setOverTime(DateUtil.offsetDay(saasTask.getTaskEnd(), 15));
                        // 自己的数据减去配置的数据,作为下一次循环的依据

                        userBuyCount = userBuyCount.subtract(configurationCount);
                    } else if (NumberUtil.equals(userBuyCount, configurationCount)) {
                        if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                            break;
                        }
                        saasUserTask.setSchedule(configurationCount);
                        saasUserTask.setVoluntarySum(0);
                        saasUserTask.setStatus(Boolean.FALSE);
                        saasUserTask.setFulfilStatus(Boolean.TRUE);
                        saasUserTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                        saasUserTask.setFulfilTime(DateUtil.date());
                        TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                        saasUserTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                        saasUserTask.setSaasType(saasTask.getSaasType());
                        saasUserTask.setStageId(taskAwardIdAndStageId.getStageId());

                        saasUserTask.setOverTime(DateUtil.offsetDay(saasTask.getTaskEnd(), 15));
                        userBuyCount = BigDecimal.ZERO;
                    } else {
                        // 否则就给未完成的数据
                        saasUserTask.setSchedule(userBuyCount);
                        saasUserTask.setFulfilStatus(Boolean.FALSE);
                        saasUserTask.setOverTime(DateUtil.offsetDay(saasTask.getTaskEnd(), 15));
                        saasUserTask.setSaasType(saasTask.getSaasType());
                        userBuyCount = BigDecimal.ZERO;
                    }
                    saasUserTask.insert();
                    list.add(saasUserTask);
                }
            } else {
                // 当存在任务的时候,则已经触发的任务加上这次的购买数量,如果大于配置的数量,那么就是完成的,否则就是未完成的,并且把多出来的部分生成一个新的任务
                // 配置
                BigDecimal configurationCount = saasTaskMeetConditions.getSchedule();
                BigDecimal add = bySaasTask.getSchedule().add(saasTaskBurialPointDTO.getSchedule());
                // 修改的同时,还要把多余的部分新增
                if (NumberUtil.isGreater(add, configurationCount)) {
                    if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                        return;
                    }
                    if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                        return;
                    }
                    bySaasTask.setSchedule(configurationCount);
                    bySaasTask.setFulfilTime(DateUtil.date());
                    bySaasTask.setFulfilStatus(Boolean.TRUE);
                    bySaasTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                    TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                    bySaasTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                    bySaasTask.setSaasType(saasTask.getSaasType());
                    bySaasTask.setStageId(taskAwardIdAndStageId.getStageId());

                    bySaasTask.updateById();
                    list.add(bySaasTask);
                    // 获取多余部分,用用户的额度+购买的额度-配置的额度就是剩余的额度
                    BigDecimal userBuyCount = add.subtract(configurationCount);
                    while (true) {
                        if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                            break;
                        }
                        SaasUserTask saasUserTask = new SaasUserTask();
                        saasUserTask.setSaasTaskId(saasTask.getId());
                        saasUserTask.setTaskTrace(saasTask.getTaskTrace());
                        saasUserTask.setUserId(saasTaskBurialPointDTO.getUserId());
                        saasUserTask.setTaskType(saasTaskBurialPointDTO.getTaskType());
                        if (NumberUtil.isLessOrEqual(userBuyCount, BigDecimal.ZERO)) {
                            break;
                        }
                        // 当购买数值比配置数值大的时候,就给直接完成的数据
                        if (NumberUtil.isGreater(userBuyCount, configurationCount)) {
                            saasUserTask.setSchedule(configurationCount);
                            saasUserTask.setVoluntarySum(0);
                            saasUserTask.setStatus(Boolean.FALSE);
                            saasUserTask.setFulfilStatus(Boolean.TRUE);
                            saasUserTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                            saasUserTask.setFulfilTime(DateUtil.date());
                            TaskAwardIdAndStageIdVO taskAwardIdAndStageIdResult = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                            saasUserTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                            saasUserTask.setStageId(taskAwardIdAndStageIdResult.getStageId());
                            saasUserTask.setSaasType(saasTask.getSaasType());

                            saasUserTask.setOverTime(DateUtil.offsetDay(saasTask.getTaskEnd(), 15));
                            // 自己的数据减去配置的数据,作为下一次循环的依据
                            userBuyCount = userBuyCount.subtract(configurationCount);
                            if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                                break;
                            }
                        } else {
                            // 否则就给未完成的数据
                            saasUserTask.setSchedule(userBuyCount);
                            saasUserTask.setFulfilStatus(Boolean.FALSE);
                            saasUserTask.setOverTime(DateUtil.offsetDay(saasTask.getTaskEnd(), 15));
                            saasUserTask.setSaasType(saasTask.getSaasType());
                            userBuyCount = BigDecimal.ZERO;
                        }
                        saasUserTask.insert();
                        list.add(saasUserTask);
                    }
                }

                // 修改的同时不新增.并且也不完成任务
                if (NumberUtil.isLess(add, configurationCount)) {
                    bySaasTask.setSchedule(add);
                    bySaasTask.updateById();
                }

                // 修改本条为完成任务
                if (NumberUtil.equals(add, configurationCount)) {
                    if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                        return;
                    }
                    if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                        return;
                    }
                    bySaasTask.setSchedule(add);
                    bySaasTask.setFulfilTime(DateUtil.date());
                    bySaasTask.setFulfilStatus(Boolean.TRUE);
                    bySaasTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                    TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                    bySaasTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                    bySaasTask.setSaasType(saasTask.getSaasType());
                    bySaasTask.setStageId(taskAwardIdAndStageId.getStageId());
                    bySaasTask.updateById();
                    list.add(bySaasTask);
                }
            }
        });
        addSaasTaskDrawPrize(list);
    }


    /**
     * 购买平台首发
     *
     * @param saasTaskBurialPointDTO
     */
    @SneakyThrows
    public void plantFistSellTotalConsumption(SaasTaskBurialPointDTO saasTaskBurialPointDTO) {
        //  获取符合条件的任务
        List<SaasTask> meetTheTask = saasTaskDao.getByTaskTypeAndValid(saasTaskBurialPointDTO.getTaskType(), saasTaskBurialPointDTO.getUserId());
        saasTaskBurialPointDTO.setValid(meetTheTask);
        // 获取任务的条件
        List<SaasUserTask> list = new ArrayList<>();
        meetTheTask.forEach(saasTask -> {

            if (saasTask.getTaskVisible().equals(SaasTaskVisibleEnum.DAO)) {
                // 如果这个任务是某个dao的任务的话,那么需要验证这个用户是否在这个dao的网体下.不是直接结束.
                if (!sublink(saasTask, saasTaskBurialPointDTO.getUserId())) {
                    return;
                }
            }
            // 根据任务的id获取任务的条件
            SaasTaskMeetConditions saasTaskMeetConditions = saasTaskMeetConditionsDao.getByTaskId(saasTask.getId());
            // 任务条件不满足
            if (BeanUtil.isEmpty(saasTaskMeetConditions)) {
                return;
            }

            /*
            用户购买的不是空的,证明用户购买是命中了的.并且他因为只要能查询出来的任务就可以去完成的.所以这里需要考虑到他的任务数量.
            1.考虑任务的剩余数量进度问题.要在修改的时候做判定.虽然查询出来的时候有大于0判定,但是要考虑事务以及并发的问题.所以一旦出现了数量不符就要回滚.
            2.考虑他超出的部分的问题,他有可能会出现有多条的情况.所以在修改原本的一条的时候,多余的部分 需要新生成多条.这个条目根据任务的配置来.
            * */
            SaasUserTask bySaasTask = saasUserTaskDao.getBySaasTask(saasTask.getId(), saasTaskBurialPointDTO.getUserId());
            if (BeanUtil.isEmpty(bySaasTask)) {
                // 当前没有执行中的任务,根据配置新增对应的份数,如果大于1的话,那么最后一份是未完成,其他的为已完成.如果为1的话则只完成一份 否则的话是未完成
                // 配置需要购买的数量
                BigDecimal configurationCount = saasTaskMeetConditions.getSchedule();
                // 用户购买的数量
                BigDecimal userBuyCount = saasTaskBurialPointDTO.getSchedule();
                // 用户购买数量大于配置的数量,那么就需要新增多份
                while (true) {
                    if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                        break;
                    }
                    SaasUserTask saasUserTask = new SaasUserTask();
                    saasUserTask.setSaasTaskId(saasTask.getId());
                    saasUserTask.setTaskTrace(saasTask.getTaskTrace());
                    saasUserTask.setUserId(saasTaskBurialPointDTO.getUserId());
                    saasUserTask.setTaskType(saasTaskBurialPointDTO.getTaskType());
                    if (NumberUtil.isLessOrEqual(userBuyCount, BigDecimal.ZERO)) {
                        break;
                    }
                    // 当购买数值比配置数值大的时候,就给直接完成的数据
                    if (NumberUtil.isGreater(userBuyCount, configurationCount)) {
                        // 任务数量是否足够
                        if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                            break;
                        }
                        saasUserTask.setSchedule(configurationCount);
                        saasUserTask.setVoluntarySum(0);
                        saasUserTask.setStatus(Boolean.FALSE);
                        saasUserTask.setFulfilStatus(Boolean.TRUE);
                        saasUserTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                        saasUserTask.setFulfilTime(DateUtil.date());
                        TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                        saasUserTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                        saasUserTask.setStageId(taskAwardIdAndStageId.getStageId());
                        saasUserTask.setSaasType(saasTask.getSaasType());
                        saasUserTask.setOverTime(DateUtil.offsetDay(saasTask.getTaskEnd(), 15));
                        // 自己的数据减去配置的数据,作为下一次循环的依据
                        userBuyCount = userBuyCount.subtract(configurationCount);
                    } else if (NumberUtil.equals(userBuyCount, configurationCount)) {
                        if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                            break;
                        }
                        saasUserTask.setSchedule(configurationCount);
                        saasUserTask.setVoluntarySum(0);
                        saasUserTask.setStatus(Boolean.FALSE);
                        saasUserTask.setFulfilStatus(Boolean.TRUE);
                        saasUserTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                        saasUserTask.setFulfilTime(DateUtil.date());
                        TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                        saasUserTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                        saasUserTask.setStageId(taskAwardIdAndStageId.getStageId());
                        saasUserTask.setSaasType(saasTask.getSaasType());
                        saasUserTask.setOverTime(DateUtil.offsetDay(saasTask.getTaskEnd(), 15));
                        userBuyCount = BigDecimal.ZERO;
                    } else {
                        // 否则就给未完成的数据
                        saasUserTask.setSchedule(userBuyCount);
                        saasUserTask.setFulfilStatus(Boolean.FALSE);
                        saasUserTask.setOverTime(DateUtil.offsetDay(saasTask.getTaskEnd(), 15));
                        saasUserTask.setSaasType(saasTask.getSaasType());
                        userBuyCount = BigDecimal.ZERO;
                    }
                    saasUserTask.insert();
                    list.add(saasUserTask);
                }
            } else {
                // 当存在任务的时候,则已经触发的任务加上这次的购买数量,如果大于配置的数量,那么就是完成的,否则就是未完成的,并且把多出来的部分生成一个新的任务
                // 配置
                BigDecimal configurationCount = saasTaskMeetConditions.getSchedule();
                BigDecimal add = bySaasTask.getSchedule().add(saasTaskBurialPointDTO.getSchedule());
                // 修改的同时,还要把多余的部分新增
                if (NumberUtil.isGreater(add, configurationCount)) {
                    if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                        return;
                    }
                    if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                        return;
                    }
                    bySaasTask.setSchedule(configurationCount);
                    bySaasTask.setFulfilTime(DateUtil.date());
                    bySaasTask.setFulfilStatus(Boolean.TRUE);
                    bySaasTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                    TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                    bySaasTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                    bySaasTask.setSaasType(saasTask.getSaasType());
                    bySaasTask.setStageId(taskAwardIdAndStageId.getStageId());
                    bySaasTask.updateById();
                    list.add(bySaasTask);
                    // 获取多余部分,用用户的额度+购买的额度-配置的额度就是剩余的额度
                    BigDecimal userBuyCount = add.subtract(configurationCount);
                    while (true) {
                        if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                            break;
                        }
                        SaasUserTask saasUserTask = new SaasUserTask();
                        saasUserTask.setSaasTaskId(saasTask.getId());
                        saasUserTask.setTaskTrace(saasTask.getTaskTrace());
                        saasUserTask.setUserId(saasTaskBurialPointDTO.getUserId());
                        saasUserTask.setTaskType(saasTaskBurialPointDTO.getTaskType());
                        if (NumberUtil.isLessOrEqual(userBuyCount, BigDecimal.ZERO)) {
                            break;
                        }
                        // 当购买数值比配置数值大的时候,就给直接完成的数据
                        if (NumberUtil.isGreater(userBuyCount, configurationCount)) {
                            saasUserTask.setSchedule(configurationCount);
                            saasUserTask.setVoluntarySum(0);
                            saasUserTask.setStatus(Boolean.FALSE);
                            saasUserTask.setFulfilStatus(Boolean.TRUE);
                            saasUserTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                            saasUserTask.setFulfilTime(DateUtil.date());
                            TaskAwardIdAndStageIdVO taskAwardIdAndStageIdResult = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                            saasUserTask.setTaskAwardId(taskAwardIdAndStageIdResult.getAwardId());
                            saasUserTask.setSaasType(saasTask.getSaasType());
                            saasUserTask.setStageId(taskAwardIdAndStageIdResult.getStageId());
                            saasUserTask.setOverTime(DateUtil.offsetDay(saasTask.getTaskEnd(), 15));
                            // 自己的数据减去配置的数据,作为下一次循环的依据
                            userBuyCount = userBuyCount.subtract(configurationCount);
                            if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                                break;
                            }
                        } else {
                            // 否则就给未完成的数据
                            saasUserTask.setSchedule(userBuyCount);
                            saasUserTask.setFulfilStatus(Boolean.FALSE);
                            saasUserTask.setOverTime(DateUtil.offsetDay(saasTask.getTaskEnd(), 15));
                            saasUserTask.setSaasType(saasTask.getSaasType());
                            userBuyCount = BigDecimal.ZERO;
                        }
                        saasUserTask.insert();
                        list.add(saasUserTask);
                    }
                }

                // 修改的同时不新增.并且也不完成任务
                if (NumberUtil.isLess(add, configurationCount)) {
                    bySaasTask.setSchedule(add);
                    bySaasTask.updateById();
                }

                // 修改本条为完成任务
                if (NumberUtil.equals(add, configurationCount)) {
                    if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                        return;
                    }
                    if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                        return;
                    }
                    bySaasTask.setSchedule(add);
                    bySaasTask.setFulfilTime(DateUtil.date());
                    bySaasTask.setFulfilStatus(Boolean.TRUE);
                    bySaasTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                    TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                    bySaasTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                    bySaasTask.setStageId(taskAwardIdAndStageId.getStageId());
                    bySaasTask.setSaasType(saasTask.getSaasType());
                    bySaasTask.updateById();
                    list.add(bySaasTask);
                }
            }
        });
        addSaasTaskDrawPrize(list);
    }

    /**
     * 购买品牌孵化累计金额
     *
     * @param saasTaskBurialPointDTO
     */
    @SneakyThrows
    public void brandIncubationTotalConsumption(SaasTaskBurialPointDTO saasTaskBurialPointDTO) {
        //  获取符合条件的任务
        List<SaasTask> meetTheTask = saasTaskDao.getByTaskTypeAndValid(saasTaskBurialPointDTO.getTaskType(), saasTaskBurialPointDTO.getUserId());
        saasTaskBurialPointDTO.setValid(meetTheTask);
        // 获取任务的条件
        List<SaasUserTask> list = new ArrayList<>();
        meetTheTask.forEach(saasTask -> {

            if (saasTask.getTaskVisible().equals(SaasTaskVisibleEnum.DAO)) {
                // 如果这个任务是某个dao的任务的话,那么需要验证这个用户是否在这个dao的网体下.不是直接结束.
                if (!sublink(saasTask, saasTaskBurialPointDTO.getUserId())) {
                    return;
                }
            }
            // 根据任务的id获取任务的条件
            SaasTaskMeetConditions saasTaskMeetConditions = saasTaskMeetConditionsDao.getByTaskId(saasTask.getId());
            // 任务条件不满足
            if (BeanUtil.isEmpty(saasTaskMeetConditions)) {
                return;
            }
            // 根据任务的条件id获取此任务是否为孵化区
            SecondCollectionConfig secondCollectionConfig = secondCollectionConfigService.getByCollectionAndType(saasTaskBurialPointDTO.getConditionId(), MarketTypeEnum.BRAND_INCUBATION);
            // 任务条件不存在则不处理
            if (Objects.isNull(secondCollectionConfig)) {
                return;
            }
            /*
            用户购买的不是空的,证明用户购买是命中了的.并且他因为只要能查询出来的任务就可以去完成的.所以这里需要考虑到他的任务数量.
            1.考虑任务的剩余数量进度问题.要在修改的时候做判定.虽然查询出来的时候有大于0判定,但是要考虑事务以及并发的问题.所以一旦出现了数量不符就要回滚.
            2.考虑他超出的部分的问题,他有可能会出现有多条的情况.所以在修改原本的一条的时候,多余的部分 需要新生成多条.这个条目根据任务的配置来.
            * */
            SaasUserTask bySaasTask = saasUserTaskDao.getBySaasTask(saasTask.getId(), saasTaskBurialPointDTO.getUserId());
            if (BeanUtil.isEmpty(bySaasTask)) {
                // 当前没有执行中的任务,根据配置新增对应的份数,如果大于1的话,那么最后一份是未完成,其他的为已完成.如果为1的话则只完成一份 否则的话是未完成
                // 配置需要购买的数量
                BigDecimal configurationCount = saasTaskMeetConditions.getSchedule();
                // 用户购买的数量
                BigDecimal userBuyCount = saasTaskBurialPointDTO.getSchedule();
                // 用户购买数量大于配置的数量,那么就需要新增多份
                while (true) {
                    if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                        break;
                    }
                    SaasUserTask saasUserTask = new SaasUserTask();
                    saasUserTask.setSaasTaskId(saasTask.getId());
                    saasUserTask.setTaskTrace(saasTask.getTaskTrace());
                    saasUserTask.setUserId(saasTaskBurialPointDTO.getUserId());
                    saasUserTask.setTaskType(saasTaskBurialPointDTO.getTaskType());
                    if (NumberUtil.isLessOrEqual(userBuyCount, BigDecimal.ZERO)) {
                        break;
                    }
                    // 当购买数值比配置数值大的时候,就给直接完成的数据
                    if (NumberUtil.isGreater(userBuyCount, configurationCount)) {
                        // 任务数量是否足够
                        if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                            break;
                        }
                        saasUserTask.setSchedule(configurationCount);
                        saasUserTask.setVoluntarySum(0);
                        saasUserTask.setStatus(Boolean.FALSE);
                        saasUserTask.setFulfilStatus(Boolean.TRUE);
                        saasUserTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                        saasUserTask.setFulfilTime(DateUtil.date());
                        TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                        saasUserTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                        saasUserTask.setStageId(taskAwardIdAndStageId.getStageId());
                        saasUserTask.setSaasType(saasTask.getSaasType());
                        saasUserTask.setOverTime(DateUtil.offsetDay(saasTask.getTaskEnd(), 15));
                        // 自己的数据减去配置的数据,作为下一次循环的依据
                        userBuyCount = userBuyCount.subtract(configurationCount);
                    } else if (NumberUtil.equals(userBuyCount, configurationCount)) {
                        if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                            break;
                        }
                        saasUserTask.setSchedule(configurationCount);
                        saasUserTask.setVoluntarySum(0);
                        saasUserTask.setStatus(Boolean.FALSE);
                        saasUserTask.setFulfilStatus(Boolean.TRUE);
                        saasUserTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                        saasUserTask.setFulfilTime(DateUtil.date());
                        TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                        saasUserTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                        saasUserTask.setStageId(taskAwardIdAndStageId.getStageId());
                        saasUserTask.setSaasType(saasTask.getSaasType());
                        saasUserTask.setOverTime(DateUtil.offsetDay(saasTask.getTaskEnd(), 15));
                        userBuyCount = BigDecimal.ZERO;
                    } else {
                        // 否则就给未完成的数据
                        saasUserTask.setSchedule(userBuyCount);
                        saasUserTask.setFulfilStatus(Boolean.FALSE);
                        saasUserTask.setOverTime(DateUtil.offsetDay(saasTask.getTaskEnd(), 15));
                        saasUserTask.setSaasType(saasTask.getSaasType());
                        userBuyCount = BigDecimal.ZERO;
                    }
                    saasUserTask.insert();
                    list.add(saasUserTask);
                }
            } else {
                // 当存在任务的时候,则已经触发的任务加上这次的购买数量,如果大于配置的数量,那么就是完成的,否则就是未完成的,并且把多出来的部分生成一个新的任务
                // 配置
                BigDecimal configurationCount = saasTaskMeetConditions.getSchedule();
                BigDecimal add = bySaasTask.getSchedule().add(saasTaskBurialPointDTO.getSchedule());
                // 修改的同时,还要把多余的部分新增
                if (NumberUtil.isGreater(add, configurationCount)) {
                    if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                        return;
                    }
                    if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                        return;
                    }
                    bySaasTask.setSchedule(configurationCount);
                    bySaasTask.setFulfilTime(DateUtil.date());
                    bySaasTask.setFulfilStatus(Boolean.TRUE);
                    bySaasTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                    TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                    bySaasTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                    bySaasTask.setSaasType(saasTask.getSaasType());
                    bySaasTask.setStageId(taskAwardIdAndStageId.getStageId());
                    bySaasTask.updateById();
                    // 获取多余部分,用用户的额度+购买的额度-配置的额度就是剩余的额度
                    list.add(bySaasTask);
                    BigDecimal userBuyCount = add.subtract(configurationCount);
                    while (true) {
                        if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                            break;
                        }
                        SaasUserTask saasUserTask = new SaasUserTask();
                        saasUserTask.setSaasTaskId(saasTask.getId());
                        saasUserTask.setTaskTrace(saasTask.getTaskTrace());
                        saasUserTask.setUserId(saasTaskBurialPointDTO.getUserId());
                        saasUserTask.setTaskType(saasTaskBurialPointDTO.getTaskType());
                        if (NumberUtil.isLessOrEqual(userBuyCount, BigDecimal.ZERO)) {
                            break;
                        }
                        // 当购买数值比配置数值大的时候,就给直接完成的数据
                        if (NumberUtil.isGreater(userBuyCount, configurationCount)) {
                            saasUserTask.setSchedule(configurationCount);
                            saasUserTask.setVoluntarySum(0);
                            saasUserTask.setStatus(Boolean.FALSE);
                            saasUserTask.setFulfilStatus(Boolean.TRUE);
                            saasUserTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                            saasUserTask.setFulfilTime(DateUtil.date());
                            TaskAwardIdAndStageIdVO taskAwardIdAndStageIdResult = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                            saasUserTask.setTaskAwardId(taskAwardIdAndStageIdResult.getAwardId());
                            saasUserTask.setSaasType(saasTask.getSaasType());
                            saasUserTask.setStageId(taskAwardIdAndStageIdResult.getStageId());
                            saasUserTask.setOverTime(DateUtil.offsetDay(saasTask.getTaskEnd(), 15));
                            // 自己的数据减去配置的数据,作为下一次循环的依据
                            userBuyCount = userBuyCount.subtract(configurationCount);
                            if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                                break;
                            }
                        } else {
                            // 否则就给未完成的数据
                            saasUserTask.setSchedule(userBuyCount);
                            saasUserTask.setFulfilStatus(Boolean.FALSE);
                            saasUserTask.setOverTime(DateUtil.offsetDay(saasTask.getTaskEnd(), 15));
                            saasUserTask.setSaasType(saasTask.getSaasType());
                            userBuyCount = BigDecimal.ZERO;
                        }
                        saasUserTask.insert();
                        list.add(saasUserTask);
                    }
                }

                // 修改的同时不新增.并且也不完成任务
                if (NumberUtil.isLess(add, configurationCount)) {
                    bySaasTask.setSchedule(add);
                    bySaasTask.updateById();
                }

                // 修改本条为完成任务
                if (NumberUtil.equals(add, configurationCount)) {
                    if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                        return;
                    }
                    if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                        return;
                    }
                    bySaasTask.setSchedule(add);
                    bySaasTask.setFulfilTime(DateUtil.date());
                    bySaasTask.setFulfilStatus(Boolean.TRUE);
                    bySaasTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                    TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                    bySaasTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                    bySaasTask.setSaasType(saasTask.getSaasType());
                    bySaasTask.setStageId(taskAwardIdAndStageId.getStageId());
                    bySaasTask.updateById();
                    list.add(bySaasTask);
                }
            }
        });
        addSaasTaskDrawPrize(list);
    }

    /**
     * 购买自由市场藏品金额
     *
     * @param saasTaskBurialPointDTO
     */
    @SneakyThrows
    public void freeMarketTotalConsumption(SaasTaskBurialPointDTO saasTaskBurialPointDTO) {
        //  获取符合条件的任务
        List<SaasTask> meetTheTask = saasTaskDao.getByTaskTypeAndValid(saasTaskBurialPointDTO.getTaskType(), saasTaskBurialPointDTO.getUserId());
        saasTaskBurialPointDTO.setValid(meetTheTask);
        // 获取任务的条件
        List<SaasUserTask> list = new ArrayList<>();
        meetTheTask.forEach(saasTask -> {

            if (saasTask.getTaskVisible().equals(SaasTaskVisibleEnum.DAO)) {
                // 如果这个任务是某个dao的任务的话,那么需要验证这个用户是否在这个dao的网体下.不是直接结束.
                if (!sublink(saasTask, saasTaskBurialPointDTO.getUserId())) {
                    return;
                }
            }
            // 根据任务的id获取任务的条件
            SaasTaskMeetConditions saasTaskMeetConditions = saasTaskMeetConditionsDao.getByTaskId(saasTask.getId());
            // 任务条件不满足
            if (BeanUtil.isEmpty(saasTaskMeetConditions)) {
                return;
            }
            // 根据任务的条件id获取此任务是否为自由市场交易
            SecondCollectionConfig secondCollectionConfig = secondCollectionConfigService.getByCollectionAndType(saasTaskBurialPointDTO.getConditionId(), MarketTypeEnum.FREE_MARKET);
            // 任务条件不存在则不处理
            if (Objects.isNull(secondCollectionConfig)) {
                return;
            }
            /*
            用户购买的不是空的,证明用户购买是命中了的.并且他因为只要能查询出来的任务就可以去完成的.所以这里需要考虑到他的任务数量.
            1.考虑任务的剩余数量进度问题.要在修改的时候做判定.虽然查询出来的时候有大于0判定,但是要考虑事务以及并发的问题.所以一旦出现了数量不符就要回滚.
            2.考虑他超出的部分的问题,他有可能会出现有多条的情况.所以在修改原本的一条的时候,多余的部分 需要新生成多条.这个条目根据任务的配置来.
            * */
            SaasUserTask bySaasTask = saasUserTaskDao.getBySaasTask(saasTask.getId(), saasTaskBurialPointDTO.getUserId());
            if (BeanUtil.isEmpty(bySaasTask)) {
                // 当前没有执行中的任务,根据配置新增对应的份数,如果大于1的话,那么最后一份是未完成,其他的为已完成.如果为1的话则只完成一份 否则的话是未完成
                // 配置需要购买的数量
                BigDecimal configurationCount = saasTaskMeetConditions.getSchedule();
                // 用户购买的数量
                BigDecimal userBuyCount = saasTaskBurialPointDTO.getSchedule();
                // 用户购买数量大于配置的数量,那么就需要新增多份
                while (true) {
                    if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                        break;
                    }
                    SaasUserTask saasUserTask = new SaasUserTask();
                    saasUserTask.setSaasTaskId(saasTask.getId());
                    saasUserTask.setTaskTrace(saasTask.getTaskTrace());
                    saasUserTask.setUserId(saasTaskBurialPointDTO.getUserId());
                    saasUserTask.setTaskType(saasTaskBurialPointDTO.getTaskType());
                    if (NumberUtil.isLessOrEqual(userBuyCount, BigDecimal.ZERO)) {
                        break;
                    }
                    // 当购买数值比配置数值大的时候,就给直接完成的数据
                    if (NumberUtil.isGreater(userBuyCount, configurationCount)) {
                        // 任务数量是否足够
                        if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                            break;
                        }
                        saasUserTask.setSchedule(configurationCount);
                        saasUserTask.setVoluntarySum(0);
                        saasUserTask.setStatus(Boolean.FALSE);
                        saasUserTask.setFulfilStatus(Boolean.TRUE);
                        saasUserTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                        saasUserTask.setFulfilTime(DateUtil.date());
                        TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                        saasUserTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                        saasUserTask.setSaasType(saasTask.getSaasType());
                        saasUserTask.setStageId(taskAwardIdAndStageId.getStageId());
                        saasUserTask.setOverTime(DateUtil.offsetDay(saasTask.getTaskEnd(), 15));
                        // 自己的数据减去配置的数据,作为下一次循环的依据
                        userBuyCount = userBuyCount.subtract(configurationCount);
                    } else if (NumberUtil.equals(userBuyCount, configurationCount)) {
                        if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                            break;
                        }
                        saasUserTask.setSchedule(configurationCount);
                        saasUserTask.setVoluntarySum(0);
                        saasUserTask.setStatus(Boolean.FALSE);
                        saasUserTask.setFulfilStatus(Boolean.TRUE);
                        saasUserTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                        saasUserTask.setFulfilTime(DateUtil.date());
                        TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                        saasUserTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                        saasUserTask.setSaasType(saasTask.getSaasType());
                        saasUserTask.setStageId(taskAwardIdAndStageId.getStageId());
                        saasUserTask.setOverTime(DateUtil.offsetDay(saasTask.getTaskEnd(), 15));
                        userBuyCount = BigDecimal.ZERO;
                    } else {
                        // 否则就给未完成的数据
                        saasUserTask.setSchedule(userBuyCount);
                        saasUserTask.setFulfilStatus(Boolean.FALSE);
                        saasUserTask.setOverTime(DateUtil.offsetDay(saasTask.getTaskEnd(), 15));
                        saasUserTask.setSaasType(saasTask.getSaasType());
                        userBuyCount = BigDecimal.ZERO;
                    }
                    saasUserTask.insert();
                    list.add(saasUserTask);
                }
            } else {
                // 当存在任务的时候,则已经触发的任务加上这次的购买数量,如果大于配置的数量,那么就是完成的,否则就是未完成的,并且把多出来的部分生成一个新的任务
                // 配置
                BigDecimal configurationCount = saasTaskMeetConditions.getSchedule();
                BigDecimal add = bySaasTask.getSchedule().add(saasTaskBurialPointDTO.getSchedule());
                // 修改的同时,还要把多余的部分新增
                if (NumberUtil.isGreater(add, configurationCount)) {
                    if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                        return;
                    }
                    if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                        return;
                    }
                    bySaasTask.setSchedule(configurationCount);
                    bySaasTask.setFulfilTime(DateUtil.date());
                    bySaasTask.setFulfilStatus(Boolean.TRUE);
                    bySaasTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                    TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                    bySaasTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                    bySaasTask.setSaasType(saasTask.getSaasType());
                    bySaasTask.setStageId(taskAwardIdAndStageId.getStageId());
                    bySaasTask.updateById();
                    // 获取多余部分,用用户的额度+购买的额度-配置的额度就是剩余的额度
                    list.add(bySaasTask);
                    BigDecimal userBuyCount = add.subtract(configurationCount);
                    while (true) {
                        if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                            break;
                        }
                        SaasUserTask saasUserTask = new SaasUserTask();
                        saasUserTask.setSaasTaskId(saasTask.getId());
                        saasUserTask.setTaskTrace(saasTask.getTaskTrace());
                        saasUserTask.setUserId(saasTaskBurialPointDTO.getUserId());
                        saasUserTask.setTaskType(saasTaskBurialPointDTO.getTaskType());
                        if (NumberUtil.isLessOrEqual(userBuyCount, BigDecimal.ZERO)) {
                            break;
                        }
                        // 当购买数值比配置数值大的时候,就给直接完成的数据
                        if (NumberUtil.isGreater(userBuyCount, configurationCount)) {
                            saasUserTask.setSchedule(configurationCount);
                            saasUserTask.setVoluntarySum(0);
                            saasUserTask.setStatus(Boolean.FALSE);
                            saasUserTask.setFulfilStatus(Boolean.TRUE);
                            saasUserTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                            saasUserTask.setFulfilTime(DateUtil.date());
                            TaskAwardIdAndStageIdVO taskAwardIdAndStageIdResult = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                            saasUserTask.setTaskAwardId(taskAwardIdAndStageIdResult.getAwardId());
                            saasUserTask.setSaasType(saasTask.getSaasType());
                            saasUserTask.setStageId(taskAwardIdAndStageIdResult.getStageId());
                            saasUserTask.setOverTime(DateUtil.offsetDay(saasTask.getTaskEnd(), 15));
                            // 自己的数据减去配置的数据,作为下一次循环的依据
                            userBuyCount = userBuyCount.subtract(configurationCount);
                            if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                                break;
                            }
                        } else {
                            // 否则就给未完成的数据
                            saasUserTask.setSchedule(userBuyCount);
                            saasUserTask.setFulfilStatus(Boolean.FALSE);
                            saasUserTask.setOverTime(DateUtil.offsetDay(saasTask.getTaskEnd(), 15));
                            saasUserTask.setSaasType(saasTask.getSaasType());
                            userBuyCount = BigDecimal.ZERO;
                        }
                        saasUserTask.insert();
                        list.add(saasUserTask);
                    }
                }

                // 修改的同时不新增.并且也不完成任务
                if (NumberUtil.isLess(add, configurationCount)) {
                    bySaasTask.setSchedule(add);
                    bySaasTask.updateById();
                }

                // 修改本条为完成任务
                if (NumberUtil.equals(add, configurationCount)) {
                    if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                        return;
                    }
                    if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                        return;
                    }
                    bySaasTask.setSchedule(add);
                    bySaasTask.setFulfilTime(DateUtil.date());
                    bySaasTask.setFulfilStatus(Boolean.TRUE);
                    bySaasTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                    TaskAwardIdAndStageIdVO taskAwardIdAndStageIdResult = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                    bySaasTask.setTaskAwardId(taskAwardIdAndStageIdResult.getAwardId());
                    bySaasTask.setSaasType(saasTask.getSaasType());
                    bySaasTask.setStageId(taskAwardIdAndStageIdResult.getStageId());
                    bySaasTask.updateById();
                    list.add(bySaasTask);
                }
            }
        });
        addSaasTaskDrawPrize(list);
    }

    @Override
    public SaasTaskWebDetailsVO saasTaskByIdCompleted(Long id, UserInfo user) {
        SaasTaskWebDetailsVO saasTaskWebDetailsVO = new SaasTaskWebDetailsVO();
        SaasUserTask saasUserTask = saasUserTaskDao.getById(id);
        Long saasTaskId = saasUserTask.getSaasTaskId();
        // 处理基础数据  一个是基础表数据,一个是该任务用户目前完成了几次
        SaasTask saasTask = saasTaskDao.getById(saasTaskId);
        saasTaskWebDetailsVO.basics(saasTask, saasUserTaskDao.countByTaskId(saasTaskId, user.getId()));

        SaasTaskMeetConditions saasTaskMeetConditions = saasTaskMeetConditionsDao.getByTaskId(saasTaskId);

        // 模板
        saasTaskWebDetailsVO.userTemplateTask(saasTaskMeetConditions, saasUserTask);
        // 完成任务模板
        saasTaskWebDetailsVO.meetConditions(saasTaskMeetConditionsDao.getByTaskId(saasTaskId));

        // 根据任务参与者进行任务条件判定.如果这个任务是持有指定藏品,才进行查询
        if (saasTaskWebDetailsVO.getTaskParticipator() == SaasTaskParticipatorEnum.HOLD_COLLECTION) {
            // 获取持有条件获取藏品.
            saasTaskWebDetailsVO.setTaskConditions(userCollectionDao.saasTaskCondition(saasTaskId, user.getId()));
        }

        // 获取任务完成模板所需要购买的藏品或者商品,根据不同的标识.进行判定
        if (saasTaskWebDetailsVO.getSaasTaskMeetConditionsWeb().getStatus().equals(2)) {
            // 获取nft藏品
            List<SaasTaskMeetConditionsOption> saasTaskMeetConditionsOptions = saasTaskMeetConditionsOptionDao.getByTaskId(saasTaskId, saasTaskWebDetailsVO.getSaasTaskMeetConditionsWeb().getId(), 2);
            // 根据id,获取藏品数据
            List<Long> conditionIds = saasTaskMeetConditionsOptions.stream().map(SaasTaskMeetConditionsOption::getConditionId).collect(Collectors.toList());
            saasTaskWebDetailsVO.setTemplateOverlength(conditionIds.size() > 3);
            if (saasTaskMeetConditionsOptions.size() > 3) {
                // 只获取conditionIds字段的前面3个.
                conditionIds = conditionIds.subList(0, 3);
            }
            List<SaasTaskDetailsCollectionVO> collectionSimplenessByIds = digitalCollectionDao.getCollectionSimplenessByIds(conditionIds);
            saasTaskWebDetailsVO.saasTaskBuys(collectionSimplenessByIds);
        }
        if (saasTaskWebDetailsVO.getSaasTaskMeetConditionsWeb().getStatus().equals(3)) {
            // 获取商城藏品
            List<SaasTaskMeetConditionsOption> saasTaskMeetConditionsOptions = saasTaskMeetConditionsOptionDao.getByTaskId(saasTaskId, saasTaskWebDetailsVO.getSaasTaskMeetConditionsWeb().getId(), 3);
            // 根据id,获取商品
            List<Long> conditionIds = saasTaskMeetConditionsOptions.stream().map(SaasTaskMeetConditionsOption::getConditionId).collect(Collectors.toList());
            saasTaskWebDetailsVO.setTemplateOverlength(conditionIds.size() > 3);
            if (saasTaskMeetConditionsOptions.size() > 3) {
                // 只获取conditionIds字段的前面3个.
                conditionIds = conditionIds.subList(0, 3);
            }
            List<SaasTaskDetailsCollectionVO> mallProductSimplenessByIds = mallProductDao.getMallProductSimplenessByIds(conditionIds);
            saasTaskWebDetailsVO.saasTaskBuys(mallProductSimplenessByIds);
        }

        // 判断这个任务有没有完成,完成的话获取的是他完成任务的时候的奖励排名
        SaasTaskStageConditions saasTaskStageConditions = null;
        if (saasUserTask.getFulfilStatus()) {
            // 完成的获取的是他完成任务的时候的奖励阶段,如果不是的话则获取的是他当前的奖励阶段
            saasTaskStageConditions = saasTaskStageConditionsDao.getById(saasUserTask.getStageId());
        } else {
            // 没完成的时候
            // 这里要根据当前的任务剩余量,去获取他的奖励
            // 已完成任务数量
            Integer offTheStocks = saasTask.getTaskTotalSum() - saasTask.getTaskResidueSum();
            // 获取上限和下限在offTheStocks之间的奖励
            saasTaskStageConditions = saasTaskStageConditionsDao.upAndDownSection(saasTaskId, offTheStocks);
        }
        // 防止下面取参数错误
        saasTaskWebDetailsVO.setSaasTaskStageConditions(saasTaskStageConditions);
        // 任务奖励基础数据
        List<SaasTaskAwardVO> byTaskIdLeftDig = saasTaskAwardDao.getByTaskIdLeftDig(saasTaskId,BeanUtil.isNotEmpty(saasTaskStageConditions)? saasTaskStageConditions.getId():null);
        // 根据任务的基础奖励数据，获取任务真实奖励
        byTaskIdLeftDig.forEach(saasTaskAwardVO -> {
            List<SaasTaskAwardDetailsVO> byTaskIdLeftEquity = saasTaskAwardDetailsDao.getByTaskIdLeftEquity(saasTaskId,saasTaskAwardVO.getId(), saasTaskAwardVO.getCollectionId());
            byTaskIdLeftEquity.forEach(saasTaskAwardDetailsVO -> {
                if (saasTaskAwardDetailsVO.getBoxEquityType().equals(BoxEquityTypeEnum.POINTS)) {
                    saasTaskAwardDetailsVO.setDescribe("星球碎片");
                }
            });
            saasTaskAwardVO.setSaasTaskAwardDetails(byTaskIdLeftEquity);
        });
        saasTaskWebDetailsVO.setSaasTaskAwards(byTaskIdLeftDig);
        // 调用方法,获取用户基础数据的排列id.获取所有的藏品,让后把用户的数据查出来.如果没有的话,则查找优先级最低的那个.如果有的话,根据藏品的id进行匹配查询出他的优先级
        List<Long> collectionIds = saasTaskWebDetailsVO.byTaskIdLeftDigCollectionId();
        // 根据上面的id，获取用户所有的藏品
        List<UserCollection> byCollectionIdAndUserId = userCollectionDao.getByCollectionIdAndUserId(collectionIds, user.getId());
        saasTaskWebDetailsVO.rewardRanking(byCollectionIdAndUserId);
        return saasTaskWebDetailsVO;
    }

    @Override
    public List<SaasTask> everydayTask() {
        return saasTaskDao.everydayTask();
    }

    @Override
    public List<SaasTask> weeklyTask() {
        return saasTaskDao.weeklyTask();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void resetTask(SaasTask saasTask) {
        // 把对应的saastask的跟踪链进行重置.
        String taskTrace = TraceContext.genTraceId();
        saasTask.setTaskTrace(taskTrace);
        saasTask.updateById();
        // 失效掉所有对应的userTask的记录
        saasUserTaskDao.updateBySaasTaskId(saasTask.getId());
        // 失效掉所有的userRecord的记录,他是邀请用户购买时候的记录
        saasTaskUserRecordDao.updateBySaasTaskId(saasTask.getId(), taskTrace);
    }

    /**
     * 获取星球任务列表
     *
     * @param pageRequest
     * @return
     */
    @Override
    public IPage<SaasTaskWebPageVO> saasTaskStarWebPage(PageRequest pageRequest) {
        return saasTaskDao.saasTaskStarWebPage(pageRequest);
    }

    @Override
    public void modificationStar(SaasTaskModificationStarDTO saasTaskModificationStarDTO) {
        if (saasTaskModificationStarDTO.validator(saasTaskDao.getById(saasTaskModificationStarDTO.getId()))) {
            // 所有的任务和任务扩展选项全都要修改
            SaasTask saasTask = BeanUtil.copyProperties(saasTaskModificationStarDTO, SaasTask.class);
            saasTask.setTaskResidueSum(saasTask.getTaskTotalSum());
            saasTask.updateById();

            // 干掉所有的对应的任务条件和扩展
            saasTaskMeetConditionsDao.deleteBySaasTaskId(saasTask.getId());
            saasTaskMeetConditionsOptionDao.deleteBySaasTaskId(saasTask.getId());
            saasTaskMeetConditionsLocationDao.deleteBySaasTaskId(saasTask.getId());

            // 组装任务条件
            saasTaskModificationStarDTO.processingTaskCondition(saasTask.getId());
            // 任务条件新增
            saasTaskMeetConditionsDao.save(saasTaskModificationStarDTO.getSaasTaskMeetConditions());

            // 新增任务条件扩展选项
            saasTaskModificationStarDTO.processingTaskConditionOption(saasTask.getId(), saasTaskModificationStarDTO.getSaasTaskMeetConditions().getId());
            List<SaasTaskMeetConditionsOption> saasTaskMeetConditionsOptions = saasTaskModificationStarDTO.getSaasTaskMeetConditionsOptions();
            if (CollUtil.isNotEmpty(saasTaskMeetConditionsOptions)) {
                saasTaskMeetConditionsOptionDao.saveBatch(saasTaskMeetConditionsOptions);
            }
            // 任务的生效位置新增.
            List<SaasTaskMeetConditionsLocation> saasTaskMeetConditionsLocations = saasTaskModificationStarDTO.getSaasTaskMeetConditionsLocations();
            if (CollUtil.isNotEmpty(saasTaskMeetConditionsLocations)) {
                saasTaskMeetConditionsLocationDao.saveBatch(saasTaskMeetConditionsLocations);
            }
        }
    }

    @Override
    public IPage<SaasTaskBasicsVO> pageStar(SaasTaskBasicsDTO saasTaskBasicsDTO) {
        return saasTaskDao.pageStar(saasTaskBasicsDTO);
    }

    public static void main(String[] args) {
        // 给定三个时间2024-06-17 00:00:00  2024-06-20 23:59:59  2024-06-07 12:34:25判断时间周期
        String dateStr = "2024-06-17 00:00:00";
        String dateStr2 = "2024-06-20 23:59:59";
        String dateStr3 = "2024-06-17 12:34:25";
        Date date = DateUtil.parse(dateStr);
        Date date1 = DateUtil.parse(dateStr2);
        Date date2 = DateUtil.parse(dateStr3);
        if (!(!date2.before(date) && !date2.after(date1))) {
            System.err.println("不在");
        }else {
            System.err.println("在");
        }

    }

    @Override
    public void submitAudit(Long id) {
        saasTaskDao.submitAudit(id);
    }

    @Override
    public void revocation(Long id) {
        RLock lock = redisson.getLock(RedisKeyEnum.SAAS_TASK_LOCK_ADMIN.getKey());
        try {
            if (lock.tryLock(30,TimeUnit.SECONDS)){
                SaasTask saasTask = saasTaskDao.getById(id);
                if (BeanUtil.isNotEmpty(saasTask)) {
                    SaasTaskConfigurationEnum taskConfiguration = saasTask.getTaskConfiguration();
                    if (taskConfiguration==SaasTaskConfigurationEnum.APPROVED) {
                        throw new GlobalRunTimeException("任务审核已通过,无法撤销");
                    }
                }
            }
            saasTaskDao.revocation(id);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }finally {
            if (lock.isLocked()) {
                lock.unlock();
            }
        }
    }
    @Override
    public List<Long> getAllSaasUnclaimedTaskAwardId() {
        return saasTaskDao.getAllSaasUnclaimedTaskAwardId();
    }

    /**
     * 发放dao的任务的奖励
     * @param list
     */
    @Override
    public void addSaasTaskDrawPrize(List<SaasUserTask> list) {
        if (CollUtil.isEmpty(list)) {
            return;
        }
        redisTemplate.opsForValue().set(StrUtil.format("addSaasTaskDrawPrize:{}:{}",list.get(0).getUserId(),list.get(0).getTaskType().name()), JSON.toJSONString(list),10, TimeUnit.MINUTES);
        // 把任务的奖励发放给用户
        List<SaasUserTask> award = list.stream().filter(saasUserTask ->saasUserTask.getFulfilStatus()!=null  && saasUserTask.getFulfilStatus()).collect(Collectors.toList());
        if (CollUtil.isEmpty(award)) {
            return;
        }
        // 把对应的奖励发放下去,
        for (SaasUserTask saasUserTask : award) {
            UserInfo user = userInfoDao.getById(saasUserTask.getUserId());
            receiveAward(saasUserTask.getId(), user);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(SaasTaskAddDTO saasTaskAddDTO) {
        SaasTask saasTask = BeanUtil.copyProperties(saasTaskAddDTO, SaasTask.class);
        saasTask.defaultAdd();
        // 获取用户dao
        saasTask.setDaoId(0L);
        saasTask.setTaskResidueSum(saasTask.getTaskTotalSum());
        saasTask.setSaasType(SaasTaskTypePlaceEnum.STAR);
        saasTask.insert();
        // 组装任务条件
        saasTaskAddDTO.processingTaskCondition(saasTask.getId());
        // 任务条件新增
        saasTaskMeetConditionsDao.save(saasTaskAddDTO.getSaasTaskMeetConditions());

        // 组装任务条件扩展选项
        saasTaskAddDTO.processingTaskConditionOption(saasTask.getId(), saasTaskAddDTO.getSaasTaskMeetConditions().getId());
        // 任务条件扩展选项新增
        List<SaasTaskMeetConditionsOption> saasTaskMeetConditionsOptions = saasTaskAddDTO.getSaasTaskMeetConditionsOptions();
        if (CollUtil.isNotEmpty(saasTaskMeetConditionsOptions)) {
            saasTaskMeetConditionsOptionDao.saveBatch(saasTaskMeetConditionsOptions);
        }
        // 任务的生效位置新增.
        List<SaasTaskMeetConditionsLocation> saasTaskMeetConditionsLocations = saasTaskAddDTO.getSaasTaskMeetConditionsLocations();
        if (CollUtil.isNotEmpty(saasTaskMeetConditionsLocations)) {
            saasTaskMeetConditionsLocationDao.saveBatch(saasTaskMeetConditionsLocations);
        }
    }

    private void taskAskFor(SaasTaskDetailsConditionVO saasTaskDetailsConditionVO, SaasTask saasTask, SaasTaskMeetConditions saasTaskMeetConditions) {
        // 购买藏品的,把藏品的数据获取出来
        if (saasTaskDetailsConditionVO.getTaskType().getConfiguration()) {
            // 获取条件关联表数据
            List<SaasTaskMeetConditionsOption> saasTaskMeetConditionsOptions = saasTaskMeetConditionsOptionDao.getByTaskId(saasTask.getId(), saasTaskMeetConditions.getId(), 2);
            List<Long> collectionIds = saasTaskMeetConditionsOptions.stream().map(SaasTaskMeetConditionsOption::getConditionId).collect(Collectors.toList());
            if (CollUtil.isNotEmpty(collectionIds)) {
                // 获取藏品数据
                List<SaasTaskDetailsCollectionVO> collectionSimplenessByIds = digitalCollectionDao.getCollectionSimplenessByIds(collectionIds);
                if (CollUtil.isNotEmpty(collectionIds)) {
                    saasTaskDetailsConditionVO.setSaasTaskDetailsCollections(collectionSimplenessByIds);
                } else {
                    throw new GlobalRunTimeException("获取藏品数据失败");
                }
            }
        }

        // 购买商城的,把商城对应的数据给返回回去
        if (saasTaskDetailsConditionVO.getTaskType() == SaasTaskTypeEnum.PURCHASE_SPECIFIED_IP_ITEMS) {
            // 获取条件关联表数据
            List<SaasTaskMeetConditionsOption> saasTaskMeetConditionsOptions = saasTaskMeetConditionsOptionDao.getByTaskId(saasTask.getId(), saasTaskMeetConditions.getId(), 3);
            List<Long> collectionIds = saasTaskMeetConditionsOptions.stream().map(SaasTaskMeetConditionsOption::getConditionId).collect(Collectors.toList());

            List<SaasTaskDetailsCollectionVO> mallProductSimplenessByIds = mallProductDao.getMallProductSimplenessByIds(collectionIds);
            if (CollUtil.isNotEmpty(mallProductSimplenessByIds)) {
                saasTaskDetailsConditionVO.setSaasTaskDetailsCollections(mallProductSimplenessByIds);
            } else {
                throw new GlobalRunTimeException("获取商城数据失败");
            }
        }
    }

    /**
     * 邀请购买指定IP藏品
     *
     * @param saasTaskBurialPointDTO
     */
    private void invitationToPurchaseSpecifiedCollections(SaasTaskBurialPointDTO saasTaskBurialPointDTO) {
        // 当前用户的上级,满足哪些任务,把满足的任务获取出来 把进度存储起来.如果他满足10个任务 那么就存储10条.满足了进度以后,直接拿来使用进行一次计算.使用过后,那一条数据就舍弃
        UserInfo userInfo = userInfoDao.getById(saasTaskBurialPointDTO.getUserId());
        if (BeanUtil.isEmpty(userInfo)) {
            log.info("用户不存在");
            return;
        }
        UserInfo recommendUser = userInfoDao.getById(userInfo.getRecommendUserId());
        if (BeanUtil.isEmpty(recommendUser)) {
            log.info("邀请人不存在");
            return;
        }
        String key = StrUtil.format("{}:{}", RedisKeyEnum.SAAS_TASK_.getKey(), recommendUser.getId());
        RLock lock = redisson.getLock(key);
        lock.lock();
        List<SaasUserTask> list = new ArrayList<>();
        try {
            // 获取邀请人的任务
            List<SaasTask> meetTheTask = saasTaskDao.getByTaskTypeAndValid(saasTaskBurialPointDTO.getTaskType(), recommendUser.getId());
            // 根据任务不同,把数据生成新的不同的数据.
            meetTheTask.forEach(saasTask -> {
                // 查看用户是否在这个DAO下
                if (saasTask.getTaskVisible().equals(SaasTaskVisibleEnum.DAO)) {
                    // 如果这个任务是某个dao的任务的话,那么需要验证这个用户是否在这个dao的网体下.不是直接结束.
                    if (!sublink(saasTask, recommendUser.getId())) {
                        return;
                    }
                }
                // 根据任务的id获取任务的条件
                SaasTaskMeetConditions saasTaskMeetConditions = saasTaskMeetConditionsDao.getByTaskId(saasTask.getId());
                // 任务条件不满足
                if (BeanUtil.isEmpty(saasTaskMeetConditions)) {
                    return;
                }
                // 根据任务的条件id获取任务的条件选项
                List<SaasTaskMeetConditionsOption> byTaskIdAndConditionId = saasTaskMeetConditionsOptionDao.getByTaskIdAndConditionId(saasTask.getId(), saasTaskBurialPointDTO.getConditionId(), 2);
                // 任务条件购买是空的,也就是说,这个藏品不需要购买.
                if (CollUtil.isEmpty(byTaskIdAndConditionId)) {
                    return;
                }
                // 先获取用户当前的存档是否存在,如果不存在的话,那么就新增一条,如果存在的话,那么就修改这条数据
                SaasTaskUserRecord saasTaskUserRecord = saasTaskUserRecordDao.getSaasTaskIdAndUserIdAndTaskTrace(saasTask.getId(), recommendUser.getId(), saasTaskBurialPointDTO.getUserId(), saasTask.getTaskTrace());
                if (BeanUtil.isEmpty(saasTaskUserRecord)) {
                    // 新增一条新的
                    SaasTaskUserRecord save = new SaasTaskUserRecord();
                    save.setSaasTaskId(saasTask.getId());
                    save.setUserId(recommendUser.getId());
                    save.setOfferUserId(saasTaskBurialPointDTO.getUserId());
                    save.setTaskTrace(saasTask.getTaskTrace());
                    save.setSchedule(saasTaskBurialPointDTO.getSchedule());
                    save.setTaskType(saasTaskBurialPointDTO.getTaskType());
                    save.insert();
                } else {
                    // 修改这条数据
                    saasTaskUserRecord.setSchedule(saasTaskUserRecord.getSchedule().add(saasTaskBurialPointDTO.getSchedule()));
                    saasTaskUserRecord.updateById();
                }
            });
            // 根据邀请人任务,开始计算任务的进度
            for (SaasTask saasTask : meetTheTask) {
                if (taskUpperLimit(saasTask, recommendUser.getId())) {
                    continue;
                }
                // 根据任务的id,资源提供者和受益者的id.获取数据,如果有的话.根据任务的配置,进行计算.如果没有的话,那么就不计算
                SaasTaskUserRecord saasTaskUserRecord = saasTaskUserRecordDao.getSaasTaskIdAndUserIdAndTaskTrace(saasTask.getId(), recommendUser.getId(), saasTaskBurialPointDTO.getUserId(), saasTask.getTaskTrace());
                if (BeanUtil.isEmpty(saasTaskUserRecord)) {
                    continue;
                }
                // 该用户已经参与过一次该任务的计算
                if (saasTaskUserRecord.getCalculate()) {
                    continue;
                }
                // 存在的情况根据配置进行计算
                SaasTaskMeetConditions saasTaskMeetConditions = saasTaskMeetConditionsDao.getByTaskId(saasTask.getId());
                // 配置
                BigDecimal configuration = saasTaskMeetConditions.getSchedule();
                // 进度
                BigDecimal schedule = saasTaskUserRecord.getSchedule();
                if (NumberUtil.isGreaterOrEqual(schedule, configuration)) {
                    // 如果说他算一个,那么这个受益用户的任务进度+1,一个版本(周期),一个用户只会提供一次受益.不会提供多次.
                    SaasUserTask bySaasTask = saasUserTaskDao.getBySaasTask(saasTask.getId(), recommendUser.getId());
                    if (BeanUtil.isEmpty(bySaasTask)) {
                        SaasUserTask saasUserTask = new SaasUserTask();
                        saasUserTask.setSaasTaskId(saasTask.getId());
                        saasUserTask.setTaskTrace(saasTask.getTaskTrace());
                        saasUserTask.setUserId(recommendUser.getId());
                        saasUserTask.setTaskType(saasTaskBurialPointDTO.getTaskType());
                        saasUserTask.setVoluntarySum(1);
                        if (saasTaskMeetConditions.getVoluntarySum() == saasUserTask.getVoluntarySum()) {
                            saasUserTask.setFulfilStatus(Boolean.TRUE);
                            TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, recommendUser.getId());
                            saasUserTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                            saasUserTask.setStageId(taskAwardIdAndStageId.getStageId());
                            saasUserTask.setSaasType(saasTask.getSaasType());
                            saasUserTask.setAccomplishSum(accomplishSum(saasTask, recommendUser.getId()));
                            saasUserTask.setFulfilTime(DateUtil.date());
                            // 任务数量是否足够
                            if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                                continue;
                            }
                        }
                        saasUserTask.setOverTime(saasTask.getTaskEnd());
                        saasTaskUserRecord.setCalculate(Boolean.TRUE);
                        saasTaskUserRecord.updateById();
                        saasUserTask.insert();
                        list.add(saasUserTask);
                    } else {
                        bySaasTask.setVoluntarySum(bySaasTask.getVoluntarySum() + 1);
                        saasTaskUserRecord.setCalculate(Boolean.TRUE);
                        // 判定是否完成任务
                        if (bySaasTask.getVoluntarySum() >= saasTaskMeetConditions.getVoluntarySum()) {
                            // 任务数量是否足够
                            if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                                continue;
                            }
                            bySaasTask.setFulfilStatus(Boolean.TRUE);
                            bySaasTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                            TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                            bySaasTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                            bySaasTask.setStageId(taskAwardIdAndStageId.getStageId());
                            bySaasTask.setSaasType(saasTask.getSaasType());
                            bySaasTask.setFulfilTime(DateUtil.date());
                        }
                        saasTaskUserRecord.updateById();
                        bySaasTask.updateById();
                        list.add(bySaasTask);
                    }
                }
            }
            addSaasTaskDrawPrize(list);
        } catch (Exception e) {
            log.info("邀请购买指定IP藏品任务埋点消费异常,异常信息:{},请求参数:{}", e.getMessage(), JSON.toJSON(saasTaskBurialPointDTO));
            e.fillInStackTrace();
        } finally {
            if (lock.isLocked()&&lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }

    /**
     * 购买指定ip藏品
     *
     * @param saasTaskBurialPointDTO
     */
    public void purchaseSpecifiedIpItems(SaasTaskBurialPointDTO saasTaskBurialPointDTO) {
        //  获取符合条件的任务
        List<SaasTask> meetTheTask = saasTaskDao.getByTaskTypeAndValid(saasTaskBurialPointDTO.getTaskType(), saasTaskBurialPointDTO.getUserId());
        saasTaskBurialPointDTO.setValid(meetTheTask);
        // 获取任务的条件
        List<SaasUserTask> list = new ArrayList<>();
        meetTheTask.forEach(saasTask -> {
            // 查询这个订单的付款时间，是否在大于任务开始时间以及小于任务结束时间,不在时间内命中的,都不允许完成任务,如果在时间内命中的则可以完成.
            MallOrder mallOrder = mallOrderDao.getById(saasTaskBurialPointDTO.getOrderId());
            if (!(mallOrder.getPayTime().after(saasTask.getTaskStart()) && mallOrder.getPayTime().before(saasTask.getTaskEnd()))) {
                return;
            }
            if (mallOrder.getActivityType() == ActivityTypeEnum.EXCHANGE) {
                return;
            }
            if (saasTask.getTaskVisible().equals(SaasTaskVisibleEnum.DAO)) {
                // 如果这个任务是某个dao的任务的话,那么需要验证这个用户是否在这个dao的网体下.不是直接结束.
                if (!sublink(saasTask, saasTaskBurialPointDTO.getUserId())) {
                    return;
                }
            }
            // 根据任务的id获取任务的条件
            SaasTaskMeetConditions saasTaskMeetConditions = saasTaskMeetConditionsDao.getByTaskId(saasTask.getId());
            // 任务条件不满足
            if (BeanUtil.isEmpty(saasTaskMeetConditions)) {
                return;
            }
            // 根据任务的条件id获取任务的条件选项
            List<SaasTaskMeetConditionsOption> byTaskIdAndConditionId = saasTaskMeetConditionsOptionDao.getByTaskIdAndConditionId(saasTask.getId(), saasTaskBurialPointDTO.getConditionId(), 3);
            // 任务条件购买是空的,也就是说,这个藏品不需要购买.
            if (CollUtil.isEmpty(byTaskIdAndConditionId)) {
                return;
            }
            /*
            用户购买的不是空的,证明用户购买是命中了的.并且他因为只要能查询出来的任务就可以去完成的.所以这里需要考虑到他的任务数量.
            1.考虑任务的剩余数量进度问题.要在修改的时候做判定.虽然查询出来的时候有大于0判定,但是要考虑事务以及并发的问题.所以一旦出现了数量不符就要回滚.
            2.考虑他超出的部分的问题,他有可能会出现有多条的情况.所以在修改原本的一条的时候,多余的部分 需要新生成多条.这个条目根据任务的配置来.
            * */
            SaasUserTask bySaasTask = saasUserTaskDao.getBySaasTask(saasTask.getId(), saasTaskBurialPointDTO.getUserId());
            if (BeanUtil.isEmpty(bySaasTask)) {
                // 当前没有执行中的任务,根据配置新增对应的份数,如果大于1的话,那么最后一份是未完成,其他的为已完成.如果为1的话则只完成一份 否则的话是未完成
                // 配置需要购买的数量
                BigDecimal configurationCount = saasTaskMeetConditions.getSchedule();
                // 用户购买的数量
                BigDecimal userBuyCount = saasTaskBurialPointDTO.getSchedule();
                // 用户购买数量大于配置的数量,那么就需要新增多份
                while (true) {
                    if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                        break;
                    }
                    SaasUserTask saasUserTask = new SaasUserTask();
                    saasUserTask.setSaasTaskId(saasTask.getId());
                    saasUserTask.setTaskTrace(saasTask.getTaskTrace());
                    saasUserTask.setUserId(saasTaskBurialPointDTO.getUserId());
                    saasUserTask.setTaskType(saasTaskBurialPointDTO.getTaskType());
                    if (NumberUtil.isLessOrEqual(userBuyCount, BigDecimal.ZERO)) {
                        break;
                    }
                    // 当购买数值比配置数值大的时候,就给直接完成的数据
                    if (NumberUtil.isGreater(userBuyCount, configurationCount)) {
                        // 任务数量是否足够
                        if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                            break;
                        }
                        saasUserTask.setSchedule(configurationCount);
                        saasUserTask.setVoluntarySum(0);
                        saasUserTask.setStatus(Boolean.FALSE);
                        saasUserTask.setFulfilStatus(Boolean.TRUE);
                        saasUserTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                        saasUserTask.setFulfilTime(DateUtil.date());
                        TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                        saasUserTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                        saasUserTask.setSaasType(saasTask.getSaasType());
                        saasUserTask.setStageId(taskAwardIdAndStageId.getStageId());
                        saasUserTask.setOverTime(DateUtil.offsetDay(saasTask.getTaskEnd(), 15));
                        // 自己的数据减去配置的数据,作为下一次循环的依据
                        userBuyCount = userBuyCount.subtract(configurationCount);
                    } else if (NumberUtil.equals(userBuyCount, configurationCount)) {
                        if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                            break;
                        }
                        saasUserTask.setSchedule(configurationCount);
                        saasUserTask.setVoluntarySum(0);
                        saasUserTask.setStatus(Boolean.FALSE);
                        saasUserTask.setFulfilStatus(Boolean.TRUE);
                        saasUserTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                        saasUserTask.setFulfilTime(DateUtil.date());
                        TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                        saasUserTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                        saasUserTask.setStageId(taskAwardIdAndStageId.getStageId());
                        saasUserTask.setSaasType(saasTask.getSaasType());
                        saasUserTask.setOverTime(DateUtil.offsetDay(saasTask.getTaskEnd(), 15));
                        userBuyCount = BigDecimal.ZERO;
                    } else {
                        // 否则就给未完成的数据
                        saasUserTask.setSchedule(userBuyCount);
                        saasUserTask.setFulfilStatus(Boolean.FALSE);
                        saasUserTask.setOverTime(DateUtil.offsetDay(saasTask.getTaskEnd(), 15));
                        saasUserTask.setSaasType(saasTask.getSaasType());
                        userBuyCount = BigDecimal.ZERO;
                    }
                    saasUserTask.insert();
                    list.add(saasUserTask);
                }
            } else {
                // 当存在任务的时候,则已经触发的任务加上这次的购买数量,如果大于配置的数量,那么就是完成的,否则就是未完成的,并且把多出来的部分生成一个新的任务
                // 配置
                BigDecimal configurationCount = saasTaskMeetConditions.getSchedule();
                BigDecimal add = bySaasTask.getSchedule().add(saasTaskBurialPointDTO.getSchedule());
                // 修改的同时,还要把多余的部分新增
                if (NumberUtil.isGreater(add, configurationCount)) {
                    if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                        return;
                    }
                    if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                        return;
                    }
                    bySaasTask.setSchedule(configurationCount);
                    bySaasTask.setFulfilTime(DateUtil.date());
                    bySaasTask.setFulfilStatus(Boolean.TRUE);
                    bySaasTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                    TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                    bySaasTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                    bySaasTask.setSaasType(saasTask.getSaasType());
                    bySaasTask.setStageId(taskAwardIdAndStageId.getStageId());
                    bySaasTask.updateById();
                    // 获取多余部分,用用户的额度+购买的额度-配置的额度就是剩余的额度
                    BigDecimal userBuyCount = add.subtract(configurationCount);
                    list.add(bySaasTask);
                    while (true) {
                        if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                            break;
                        }
                        SaasUserTask saasUserTask = new SaasUserTask();
                        saasUserTask.setSaasTaskId(saasTask.getId());
                        saasUserTask.setTaskTrace(saasTask.getTaskTrace());
                        saasUserTask.setUserId(saasTaskBurialPointDTO.getUserId());
                        saasUserTask.setTaskType(saasTaskBurialPointDTO.getTaskType());
                        if (NumberUtil.isLessOrEqual(userBuyCount, BigDecimal.ZERO)) {
                            break;
                        }
                        // 当购买数值比配置数值大的时候,就给直接完成的数据
                        if (NumberUtil.isGreater(userBuyCount, configurationCount)) {
                            saasUserTask.setSchedule(configurationCount);
                            saasUserTask.setVoluntarySum(0);
                            saasUserTask.setStatus(Boolean.FALSE);
                            saasUserTask.setFulfilStatus(Boolean.TRUE);
                            saasUserTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                            saasUserTask.setFulfilTime(DateUtil.date());
                            TaskAwardIdAndStageIdVO taskAwardIdAndStageIdResult = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                            saasUserTask.setTaskAwardId(taskAwardIdAndStageIdResult.getAwardId());
                            saasUserTask.setStageId(taskAwardIdAndStageIdResult.getStageId());
                            saasUserTask.setSaasType(saasTask.getSaasType());
                            saasUserTask.setOverTime(DateUtil.offsetDay(saasTask.getTaskEnd(), 15));
                            // 自己的数据减去配置的数据,作为下一次循环的依据
                            userBuyCount = userBuyCount.subtract(configurationCount);
                            if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                                break;
                            }
                        } else {
                            // 否则就给未完成的数据
                            saasUserTask.setSchedule(userBuyCount);
                            saasUserTask.setFulfilStatus(Boolean.FALSE);
                            saasUserTask.setOverTime(DateUtil.offsetDay(saasTask.getTaskEnd(), 15));
                            saasUserTask.setSaasType(saasTask.getSaasType());
                            userBuyCount = BigDecimal.ZERO;
                        }
                        saasUserTask.insert();
                        list.add(saasUserTask);
                    }
                }

                // 修改的同时不新增.并且也不完成任务
                if (NumberUtil.isLess(add, configurationCount)) {
                    bySaasTask.setSchedule(add);
                    bySaasTask.updateById();
                }

                // 修改本条为完成任务
                if (NumberUtil.equals(add, configurationCount)) {
                    if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                        return;
                    }
                    if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                        return;
                    }
                    bySaasTask.setSchedule(add);
                    bySaasTask.setFulfilTime(DateUtil.date());
                    bySaasTask.setFulfilStatus(Boolean.TRUE);
                    bySaasTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                    TaskAwardIdAndStageIdVO taskAwardIdAndStageIdResult = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                    bySaasTask.setTaskAwardId(taskAwardIdAndStageIdResult.getAwardId());
                    bySaasTask.setSaasType(saasTask.getSaasType());
                    bySaasTask.setStageId(taskAwardIdAndStageIdResult.getStageId());
                    bySaasTask.updateById();
                    list.add(bySaasTask);
                }
            }
        });
        addSaasTaskDrawPrize(list);
    }

    /**
     * 新用户首次消费
     *
     * @param taskBurialPointDTO
     */
    private void firstTimeConsumption(SaasTaskBurialPointDTO taskBurialPointDTO) {
        List<SaasUserTask> byTaskTypeAndUserId = saasUserTaskDao.getByTaskTypeAndUserId(taskBurialPointDTO.getTaskType(), taskBurialPointDTO.getUserId());
        if (CollUtil.isNotEmpty(byTaskTypeAndUserId)) {
            log.info("该用户已经完成首单任务,不需要做任何操作,参数:{}", JSON.toJSON(taskBurialPointDTO));
            return;
        }
        // 根据任务获取正在进行中且未完成的首次开通钱包任务,查询是否存在.
        List<SaasTask> meetTheTask = saasTaskDao.getByTaskTypeAndValid(taskBurialPointDTO.getTaskType(), taskBurialPointDTO.getUserId());
        // 没有任务,则不需要做任何操作.
        if (CollUtil.isEmpty(meetTheTask)) {
            log.info("没有任务,则不需要做任何操作,参数:{}", JSON.toJSON(taskBurialPointDTO));
            return;
        }

        //统计已成交订单数
        Integer totalCount = countOrders(taskBurialPointDTO);

        //非首单
        if (totalCount != 1) {
            log.info("不符合首单任务条件,则不需要做任何操作");
            return;
        }
        // 如果是dao的任务,那么需要验证该用户是否在dao内.
        List<SaasUserTask> list = new ArrayList<>();
        meetTheTask.forEach(saasTask -> {
            // 任务消费的时候进行加锁,锁住一条任务,依次消费,需要防止的内容是阶段性的任务获取数量不对导致异常,也要排除掉并发的场景,所以在这里用锁对他进行控制
            if (saasTask.getTaskVisible().equals(SaasTaskVisibleEnum.DAO)) {
                // 如果这个任务是某个dao的任务的话,那么需要验证这个用户是否在这个dao的网体下.不是直接结束.
                if (!sublink(saasTask, taskBurialPointDTO.getUserId())) {
                    return;
                }
            }
            // 任务可完成数量-1  如果任务可完成数量为0,那么就是不可完成的任务. 就不需要落库了.
            if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                return;
            }

            // 任务完成上限
            if (taskUpperLimit(saasTask, taskBurialPointDTO.getUserId())) {
                return;
            }
            SaasUserTask saasUserTask = new SaasUserTask();
            saasUserTask.setSaasTaskId(saasTask.getId());
            saasUserTask.setAccomplishSum(1);
            saasUserTask.setTaskTrace(saasTask.getTaskTrace());
            saasUserTask.setUserId(taskBurialPointDTO.getUserId());
            saasUserTask.setTaskType(taskBurialPointDTO.getTaskType());
            saasUserTask.setSchedule(BigDecimal.ONE);
            saasUserTask.setVoluntarySum(0);
            saasUserTask.setStatus(Boolean.FALSE);
            // 需要根据任务的配置,给用户发放奖励.
            TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, taskBurialPointDTO.getUserId());
            saasUserTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
            saasUserTask.setStageId(taskAwardIdAndStageId.getStageId());
            saasUserTask.setSaasType(saasTask.getSaasType());
            saasUserTask.setFulfilStatus(Boolean.TRUE);
            saasUserTask.setFulfilTime(DateUtil.date());
            saasUserTask.setOverTime(saasTask.getTaskEnd());
            saasUserTask.setSaasType(saasTask.getSaasType());
            list.add(saasUserTask);
        });
        log.info("数据落库.请求参数:{},落库参数:{}", JSON.toJSON(list), JSON.toJSON(taskBurialPointDTO));
        // 数据落库
        saasUserTaskDao.saveBatch(list);
        addSaasTaskDrawPrize(list);
    }

    /**
     * 购买指定藏品
     *
     * @param saasTaskBurialPointDTO
     */
    private void purchaseOfDesignatedCollection(SaasTaskBurialPointDTO saasTaskBurialPointDTO) {
//        log.info("购买指定藏品任务埋点消费.请求参数:{}", JSON.toJSON(saasTaskBurialPointDTO));
        //  获取符合条件的任务
        List<SaasTask> meetTheTask = saasTaskDao.getByTaskTypeAndValid(saasTaskBurialPointDTO.getTaskType(), saasTaskBurialPointDTO.getUserId());
        saasTaskBurialPointDTO.setValid(meetTheTask);
        List<SaasUserTask> list = new ArrayList<>();
        // 获取任务的条件
        meetTheTask.forEach(saasTask -> {
            if (saasTask.getTaskVisible().equals(SaasTaskVisibleEnum.DAO)) {
                // 如果这个任务是某个dao的任务的话,那么需要验证这个用户是否在这个dao的网体下.不是直接结束.
                if (!sublink(saasTask, saasTaskBurialPointDTO.getUserId())) {
                    return;
                }
            }

            // 根据任务的id获取任务的条件
            SaasTaskMeetConditions saasTaskMeetConditions = saasTaskMeetConditionsDao.getByTaskId(saasTask.getId());
            // 任务条件不满足
            if (BeanUtil.isEmpty(saasTaskMeetConditions)) {
                return;
            }
            // 根据任务的条件id获取任务的条件选项
            List<SaasTaskMeetConditionsOption> byTaskIdAndConditionId = saasTaskMeetConditionsOptionDao.getByTaskIdAndConditionId(saasTask.getId(), saasTaskBurialPointDTO.getConditionId(), 2);
            // 任务条件购买是空的,也就是说,这个藏品不需要购买.
            if (CollUtil.isEmpty(byTaskIdAndConditionId)) {
                return;
            }
            // 要考虑用户购买条件和持有条件相同的情况,如果用户购买的藏品和持有的藏品相同,那么先就看用户买的数量和持有数量是否相等,如果持有数量>购买数量 则代表他之前有持有
            List<SaasTaskMeetConditionsOption> isHoldCollection = saasTaskMeetConditionsOptionDao.getByTaskIdAndConditionId(saasTask.getId(), saasTaskBurialPointDTO.getConditionId(), 1);
            if (!CollUtil.isEmpty(isHoldCollection)) {
                // 验证用户的持有数量和完成数量是否一致
                Integer countByCollercitonIdAndUserId = userCollectionDao.getCountByCollercitonIdAndUserId(saasTaskBurialPointDTO.getUserId(), saasTaskBurialPointDTO.getConditionId());
                if (NumberUtil.isLessOrEqual(Convert.toBigDecimal(countByCollercitonIdAndUserId), saasTaskBurialPointDTO.getSchedule())) {
                    return;
                }
            }
            /*
            用户购买的不是空的,证明用户购买是命中了的.并且他因为只要能查询出来的任务就可以去完成的.所以这里需要考虑到他的任务数量.
            1.考虑任务的剩余数量进度问题.要在修改的时候做判定.虽然查询出来的时候有大于0判定,但是要考虑事务以及并发的问题.所以一旦出现了数量不符就要回滚.
            2.考虑他超出的部分的问题,他有可能会出现有多条的情况.所以在修改原本的一条的时候,多余的部分 需要新生成多条.这个条目根据任务的配置来.
            * */
            SaasUserTask bySaasTask = saasUserTaskDao.getBySaasTask(saasTask.getId(), saasTaskBurialPointDTO.getUserId());
            if (BeanUtil.isEmpty(bySaasTask)) {
                // 当前没有执行中的任务,根据配置新增对应的份数,如果大于1的话,那么最后一份是未完成,其他的为已完成.如果为1的话则只完成一份 否则的话是未完成
                // 配置需要购买的数量
                BigDecimal configurationCount = saasTaskMeetConditions.getSchedule();
                // 用户购买的数量
                BigDecimal userBuyCount = saasTaskBurialPointDTO.getSchedule();
                // 用户购买数量大于配置的数量,那么就需要新增多份
                while (true) {
                    if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                        break;
                    }
                    SaasUserTask saasUserTask = new SaasUserTask();
                    saasUserTask.setSaasTaskId(saasTask.getId());
                    saasUserTask.setTaskTrace(saasTask.getTaskTrace());
                    saasUserTask.setUserId(saasTaskBurialPointDTO.getUserId());
                    saasUserTask.setTaskType(saasTaskBurialPointDTO.getTaskType());
                    if (NumberUtil.isLessOrEqual(userBuyCount, BigDecimal.ZERO)) {
                        break;
                    }
                    // 当购买数值比配置数值大的时候,就给直接完成的数据
                    if (NumberUtil.isGreater(userBuyCount, configurationCount)) {
                        // 任务数量是否足够
                        if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                            break;
                        }
                        saasUserTask.setSchedule(configurationCount);
                        saasUserTask.setVoluntarySum(0);
                        saasUserTask.setStatus(Boolean.FALSE);
                        saasUserTask.setFulfilStatus(Boolean.TRUE);
                        saasUserTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                        saasUserTask.setFulfilTime(DateUtil.date());
                        TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                        saasUserTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                        saasUserTask.setSaasType(saasTask.getSaasType());
                        saasUserTask.setStageId(taskAwardIdAndStageId.getStageId());
                        saasUserTask.setOverTime(saasTask.getTaskEnd());
                        // 自己的数据减去配置的数据,作为下一次循环的依据
                        userBuyCount = userBuyCount.subtract(configurationCount);
                    } else if (NumberUtil.equals(userBuyCount, configurationCount)) {
                        // 任务数量是否足够
                        if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                            break;
                        }
                        // 否则就给未完成的数据
                        saasUserTask.setSchedule(configurationCount);
                        saasUserTask.setVoluntarySum(0);
                        saasUserTask.setStatus(Boolean.FALSE);
                        saasUserTask.setFulfilStatus(Boolean.TRUE);
                        saasUserTask.setFulfilTime(DateUtil.date());
                        saasUserTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                        TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                        saasUserTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                        saasUserTask.setSaasType(saasTask.getSaasType());
                        saasUserTask.setStageId(taskAwardIdAndStageId.getStageId());
                        saasUserTask.setOverTime(saasTask.getTaskEnd());
                        userBuyCount = BigDecimal.ZERO;
                    } else {
                        // 否则就给未完成的数据
                        saasUserTask.setSchedule(userBuyCount);
                        saasUserTask.setFulfilStatus(Boolean.FALSE);
                        saasUserTask.setOverTime(saasTask.getTaskEnd());
                        saasUserTask.setSaasType(saasTask.getSaasType());
                        userBuyCount = BigDecimal.ZERO;
                    }
                    saasUserTask.insert();
                    list.add(saasUserTask);
                }
            } else {
                // 当存在任务的时候,则已经触发的任务加上这次的购买数量,如果大于配置的数量,那么就是完成的,否则就是未完成的,并且把多出来的部分生成一个新的任务
                // 配置
                BigDecimal configurationCount = saasTaskMeetConditions.getSchedule();
                BigDecimal add = bySaasTask.getSchedule().add(saasTaskBurialPointDTO.getSchedule());
                // 修改的同时,还要把多余的部分新增
                if (NumberUtil.isGreater(add, configurationCount)) {
                    // 任务数量是否足够
                    if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                        return;
                    }

                    if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                        return;
                    }
                    bySaasTask.setSchedule(configurationCount);
                    bySaasTask.setFulfilTime(DateUtil.date());
                    bySaasTask.setFulfilStatus(Boolean.TRUE);
                    bySaasTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                    TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                    bySaasTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                    bySaasTask.setSaasType(saasTask.getSaasType());
                    bySaasTask.setStageId(taskAwardIdAndStageId.getStageId());
                    bySaasTask.updateById();
                    list.add(bySaasTask);
                    // 获取多余部分,用用户的额度+购买的额度-配置的额度就是剩余的额度
                    BigDecimal userBuyCount = add.subtract(configurationCount);
                    while (true) {
                        if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                            return;
                        }
                        SaasUserTask saasUserTask = new SaasUserTask();
                        saasUserTask.setSaasTaskId(saasTask.getId());
                        saasUserTask.setTaskTrace(saasTask.getTaskTrace());
                        saasUserTask.setUserId(saasTaskBurialPointDTO.getUserId());
                        saasUserTask.setTaskType(saasTaskBurialPointDTO.getTaskType());
                        if (NumberUtil.isLessOrEqual(userBuyCount, BigDecimal.ZERO)) {
                            break;
                        }
                        // 当购买数值比配置数值大的时候,就给直接完成的数据
                        if (NumberUtil.isGreater(userBuyCount, configurationCount)) {
                            // 任务数量是否足够
                            if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                                return;
                            }
                            saasUserTask.setSchedule(configurationCount);
                            saasUserTask.setVoluntarySum(0);
                            saasUserTask.setStatus(Boolean.FALSE);
                            saasUserTask.setFulfilStatus(Boolean.TRUE);
                            saasUserTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                            saasUserTask.setFulfilTime(DateUtil.date());
                            TaskAwardIdAndStageIdVO taskAwardIdAndStageId1 = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                            saasUserTask.setTaskAwardId(taskAwardIdAndStageId1.getAwardId());
                            saasUserTask.setSaasType(saasTask.getSaasType());
                            saasUserTask.setStageId(taskAwardIdAndStageId1.getStageId());
                            saasUserTask.setOverTime(saasTask.getTaskEnd());
                            // 自己的数据减去配置的数据,作为下一次循环的依据
                            userBuyCount = userBuyCount.subtract(configurationCount);
                        } else {
                            // 否则就给未完成的数据
                            saasUserTask.setSchedule(userBuyCount);
                            saasUserTask.setFulfilStatus(Boolean.FALSE);
                            saasUserTask.setOverTime(saasTask.getTaskEnd());
                            saasUserTask.setSaasType(saasTask.getSaasType());
                            userBuyCount = BigDecimal.ZERO;
                        }
                        saasUserTask.insert();
                        list.add(saasUserTask);
                    }
                }

                // 修改的同时不新增.并且也不完成任务
                if (NumberUtil.isLess(add, configurationCount)) {
                    bySaasTask.setSchedule(add);
                    bySaasTask.updateById();
                }

                // 修改本条为完成任务
                if (NumberUtil.equals(add, configurationCount)) {
                    if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                        return;
                    }
                    bySaasTask.setSchedule(add);
                    bySaasTask.setFulfilTime(DateUtil.date());
                    bySaasTask.setFulfilStatus(Boolean.TRUE);
                    bySaasTask.setAccomplishSum(accomplishSum(saasTask, saasTaskBurialPointDTO.getUserId()));
                    TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                    bySaasTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                    bySaasTask.setSaasType(saasTask.getSaasType());
                    bySaasTask.setStageId(taskAwardIdAndStageId.getStageId());
                    bySaasTask.updateById();
                    list.add(bySaasTask);
                }
            }

        });
        addSaasTaskDrawPrize(list);
    }

    /**
     * 邀请首次消费
     *
     * @param saasTaskBurialPointDTO
     */
    @SneakyThrows
    public void firstTimeConsumptionInvitation(SaasTaskBurialPointDTO saasTaskBurialPointDTO) {
        Thread.sleep(1000);
        log.info("进入邀请首次消费逻辑,消费参数:{}", JSON.toJSON(saasTaskBurialPointDTO));
        // 根据任务获取正在进行中且未完成的首次消费任务,查询是否存在.
        UserInfo userInfo = userInfoDao.getById(saasTaskBurialPointDTO.getUserId());
        List<SaasTask> meetTheTask = saasTaskDao.getByTaskTypeAndValid(saasTaskBurialPointDTO.getTaskType(), userInfo.getRecommendUserId());
        // 没有任务,则不需要做任何操作.
        if (CollUtil.isEmpty(meetTheTask)) {
            log.info("没有任务,则不需要做任何操作,参数:{}", JSON.toJSON(saasTaskBurialPointDTO));
            return;
        }
        //统计已成交订单数
        Integer totalCount = countOrders(saasTaskBurialPointDTO);

        //非首单
        if (totalCount != 1) {
            log.info("不符合首单任务条件,则不需要做任何操作");
            return;
        }

        // 到这里,用户是首次开通钱包,并且有任务,那么就需要给邀请人发放奖励.
        List<SaasUserTask> list = new ArrayList<>();
        // 获取邀请人的id
        if (userInfo.getRecommendUserId() != null) {
            meetTheTask.forEach(saasTask -> {
                if (saasTask.getTaskVisible().equals(SaasTaskVisibleEnum.DAO)) {
                    // 如果这个任务是某个dao的任务的话,那么需要验证这个用户是否在这个dao的网体下.不是直接结束.
                    if (!sublink(saasTask, userInfo.getRecommendUserId())) {
                        return;
                    }
                }

                SaasTaskMeetConditions saasTaskMeetConditions = saasTaskMeetConditionsDao.getByTaskId(saasTask.getId());
                // 查询当前任务用户是否有进行中的,如果有的话,就在这里进行相加并且判定是否满足.如果没有的话,就新增一条并且判定是否满足
                SaasUserTask saasUserTask = saasUserTaskDao.getBySaasTask(saasTask.getId(), userInfo.getRecommendUserId());
                if (BeanUtil.isEmpty(saasUserTask)) {
                    if (taskUpperLimit(saasTask, userInfo.getRecommendUserId())) {
                        return;
                    }
                    // 没有数据,新增一条
                    SaasUserTask save = new SaasUserTask();
                    save.setSaasTaskId(saasTask.getId());
                    save.setTaskTrace(saasTask.getTaskTrace());
                    save.setUserId(userInfo.getRecommendUserId());
                    save.setTaskType(saasTaskBurialPointDTO.getTaskType());
                    save.setSchedule(BigDecimal.ONE);
                    save.setVoluntarySum(1);
                    save.setOverTime(saasTask.getTaskEnd());
                    // 判定条件,需要邀请多少人,才可以完成任务,如果条件为1或者不需要限制的话
                    if (saasTaskMeetConditions.getVoluntarySum() <= 1) {
                        // 任务数量-1的情况下,是否有任务额度
                        if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                            return;
                        }
                        save.setFulfilStatus(Boolean.TRUE);
                        save.setFulfilTime(DateUtil.date());
                        save.setAccomplishSum(accomplishSum(saasTask, userInfo.getRecommendUserId()));
                        TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                        save.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                        save.setSaasType(saasTask.getSaasType());
                        save.setStageId(taskAwardIdAndStageId.getStageId());
                        list.add(save);
                    } else {
                        save.setFulfilStatus(Boolean.FALSE);
                    }
                    save.insert();
                } else {
                    if (taskUpperLimit(saasTask, userInfo.getRecommendUserId())) {
                        return;
                    }
                    // 有数据,修改数据
                    saasUserTask.setSchedule(saasUserTask.getSchedule().add(BigDecimal.ONE));
                    saasUserTask.setVoluntarySum(saasUserTask.getVoluntarySum() + 1);
                    // 判定条件,需要邀请多少人,才可以完成任务
                    if (saasTaskMeetConditions.getVoluntarySum() <= saasUserTask.getVoluntarySum()) {
                        // 任务数量-1的情况下,是否有任务额度
                        if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                            return;
                        }
                        saasUserTask.setFulfilStatus(Boolean.TRUE);
                        saasUserTask.setFulfilTime(DateUtil.date());
                        saasUserTask.setAccomplishSum(accomplishSum(saasTask, userInfo.getRecommendUserId()));
                        TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                        saasUserTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                        saasUserTask.setSaasType(saasTask.getSaasType());
                        saasUserTask.setStageId(taskAwardIdAndStageId.getStageId());
                        list.add(saasUserTask);
                    } else {
                        saasUserTask.setFulfilStatus(Boolean.FALSE);
                    }
                    saasUserTask.updateById();
                }
            });
        } else {
            log.info("该用户没有邀请人,不需要做任何操作,参数:{}", JSON.toJSON(saasTaskBurialPointDTO));
        }
        addSaasTaskDrawPrize(list);
    }

    /**
     * 邀请首次开通钱包
     *
     * @param saasTaskBurialPointDTO
     */
    @SneakyThrows
    public void firstTimeOpenWalletInvitation(SaasTaskBurialPointDTO saasTaskBurialPointDTO) {
        Thread.sleep(1000);
        log.info("进入邀请首次开通钱包消费,消费参数:{}", JSON.toJSON(saasTaskBurialPointDTO));
        // 根据任务获取正在进行中且未完成的首次开通钱包任务,查询是否存在.
        UserInfo userInfo = userInfoDao.getById(saasTaskBurialPointDTO.getUserId());
        List<SaasTask> meetTheTask = saasTaskDao.getByTaskTypeAndValid(saasTaskBurialPointDTO.getTaskType(), userInfo.getRecommendUserId());
        // 没有任务,则不需要做任何操作.
        if (CollUtil.isEmpty(meetTheTask)) {
            log.info("没有任务,则不需要做任何操作,参数:{}", JSON.toJSON(saasTaskBurialPointDTO));
            return;
        }

//        // 通过Java8表达式获取meetTheTask中的daoId转换为一个新的集合
//        List<Long> daoIds = meetTheTask.stream().map(SaasTask::getDaoId).collect(Collectors.toList());
//        List<UserCreatorInfo> userCreatorInfoss = userCreatorInfoDao.getDaoIds(daoIds);
//        // 获取userCreatorInfoss中的userId集合
//        List<Long> userIds = userCreatorInfoss.stream().map(UserCreatorInfo::getUserId).collect(Collectors.toList());
//        // 通过这个userIds对用户的层级关联表进行查询,获取到lv字段,然后进行升序排序
//        List<UserRelevance> userLevelRelations = userRelevanceDao.getByUserIdsAndRelevance(userIds, saasTaskBurialPointDTO.getUserId());
//        if (CollUtil.isEmpty(userLevelRelations)) {
//            return;
//        }
//        List<SaasTask> realTask=new ArrayList<>();
//        // 这个用户就是他最近的可完成任务的dao
//        for (UserRelevance userLevelRelation : userLevelRelations) {
//            // 通过userRelevance的userId获取userCreatorInfoss匹配的数据
//            List<UserCreatorInfo> collect = userCreatorInfoss.stream().filter(userCreatorInfo -> userCreatorInfo.getUserId().equals(userLevelRelation.getUserId())).collect(Collectors.toList());
//            if (CollUtil.isEmpty(collect)) {
//                continue;
//            }
//            // 获取到对应的dao,通过这个dao获取到指定的任务
//            UserCreatorInfo userCreatorInfo = collect.get(0);
//            // 获取真实最近的应该完成的认证任务
//            List<SaasTask> saasTasks = meetTheTask.stream().filter(saasTask -> userCreatorInfo.getId().equals(saasTask.getDaoId())).collect(Collectors.toList());
//            if (CollUtil.isNotEmpty(saasTasks)) {
//                realTask.addAll(0,saasTasks);
//                break;
//            }
//        }
//        // 清空原有的任务
//        meetTheTask.clear();
//        // 赋值新的任务,里面只会有一个才是对的
//        meetTheTask.addAll(realTask);


        // 查询用户目前是否是首次开通钱包.这里需要查询三个.连连 汇付 杉德
        // 钱包数量
        int walletSum = 0;
        // 杉德

        if (BeanUtil.isNotEmpty(userInfo)) {
            if (userInfo.getSandAccountOpen()) {
                walletSum = walletSum + 1;
            }
        }

        // 汇付
//        UserHfExt userHfExt = userHfExtDao.findByUserId(saasTaskBurialPointDTO.getUserId());
//        if (BeanUtil.isNotEmpty(userHfExt)) {
//            if (userHfExt.getStatus().equals(AccountStatusEnum.SUCCESS)) {
//                walletSum = walletSum + 1;
//            }
//        }

        // 连连
        LlUserExt llUserExt = llUserExtDao.getByUserId(saasTaskBurialPointDTO.getUserId());
        if (BeanUtil.isNotEmpty(llUserExt)) {
            if (llUserExt.getStatus().equals(AccountStatusEnum.SUCCESS)) {
                walletSum = walletSum + 1;
            }
        }

        UserHnaExt userHnaExt = userHnaExtDao.getByUserId(saasTaskBurialPointDTO.getUserId());
        if (BeanUtil.isNotEmpty(userHnaExt)) {
            if (userHnaExt.getStatus().equals(AccountStatusEnum.SUCCESS)) {
                walletSum = walletSum + 1;
            }
        }
        // 记录开通数据,如果只有1的话,就是首次开通钱包.在考虑事务提交的场景下.他有可能会出现0的问题,查询不到 因为事务没提交,这个时候也给他算.
        if (walletSum > 1) {
            log.info("该用户已经开通过钱包,不需要做任何操作,参数:{}", JSON.toJSON(saasTaskBurialPointDTO));
            return;
        }

        // 到这里,用户是首次开通钱包,并且有任务,那么就需要给邀请人发放奖励.
        List<SaasUserTask> list = new ArrayList<>();
        // 获取邀请人的id
        if (userInfo.getRecommendUserId() != null) {
            meetTheTask.forEach(saasTask -> {
                if (saasTask.getTaskVisible().equals(SaasTaskVisibleEnum.DAO)) {
                    // 如果这个任务是某个dao的任务的话,那么需要验证这个用户是否在这个dao的网体下.不是直接结束.
                    if (!sublink(saasTask, userInfo.getRecommendUserId())) {
                        return;
                    }
                }

                SaasTaskMeetConditions saasTaskMeetConditions = saasTaskMeetConditionsDao.getByTaskId(saasTask.getId());
                // 查询当前任务用户是否有进行中的,如果有的话,就在这里进行相加并且判定是否满足.如果没有的话,就新增一条并且判定是否满足
                SaasUserTask saasUserTask = saasUserTaskDao.getBySaasTask(saasTask.getId(), userInfo.getRecommendUserId());
                if (BeanUtil.isEmpty(saasUserTask)) {
                    if (taskUpperLimit(saasTask, userInfo.getRecommendUserId())) {
                        return;
                    }
                    // 没有数据,新增一条
                    SaasUserTask save = new SaasUserTask();
                    save.setSaasTaskId(saasTask.getId());
                    save.setTaskTrace(saasTask.getTaskTrace());
                    save.setUserId(userInfo.getRecommendUserId());
                    save.setTaskType(saasTaskBurialPointDTO.getTaskType());
                    save.setSchedule(BigDecimal.ONE);
                    save.setVoluntarySum(1);
                    save.setOverTime(saasTask.getTaskEnd());
                    // 判定条件,需要邀请多少人,才可以完成任务,如果条件为1或者不需要限制的话
                    if (saasTaskMeetConditions.getVoluntarySum() <= 1) {
                        // 任务数量-1的情况下,是否有任务额度
                        if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                            return;
                        }
                        save.setFulfilStatus(Boolean.TRUE);
                        save.setFulfilTime(DateUtil.date());
                        save.setAccomplishSum(accomplishSum(saasTask, userInfo.getRecommendUserId()));
                        TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                        save.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                        save.setSaasType(saasTask.getSaasType());
                        save.setStageId(taskAwardIdAndStageId.getStageId());
                    } else {
                        save.setFulfilStatus(Boolean.FALSE);
                    }
                    save.insert();
                    list.add(save);
                } else {
                    if (taskUpperLimit(saasTask, userInfo.getRecommendUserId())) {
                        return;
                    }
                    // 有数据,修改数据
                    saasUserTask.setSchedule(saasUserTask.getSchedule().add(BigDecimal.ONE));
                    saasUserTask.setVoluntarySum(saasUserTask.getVoluntarySum() + 1);
                    // 判定条件,需要邀请多少人,才可以完成任务
                    if (saasTaskMeetConditions.getVoluntarySum() <= saasUserTask.getVoluntarySum()) {
                        // 任务数量-1的情况下,是否有任务额度
                        if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                            return;
                        }
                        saasUserTask.setFulfilStatus(Boolean.TRUE);
                        saasUserTask.setFulfilTime(DateUtil.date());
                        saasUserTask.setAccomplishSum(accomplishSum(saasTask, userInfo.getRecommendUserId()));
                        TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
                        saasUserTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
                        saasUserTask.setSaasType(saasTask.getSaasType());
                        saasUserTask.setStageId(taskAwardIdAndStageId.getStageId());
                    } else {
                        saasUserTask.setFulfilStatus(Boolean.FALSE);
                    }
                    saasUserTask.updateById();
                    list.add(saasUserTask);
                }
            });
        } else {
            log.info("该用户没有邀请人,不需要做任何操作,参数:{}", JSON.toJSON(saasTaskBurialPointDTO));
        }
        addSaasTaskDrawPrize(list);
    }

    /**
     * 首次开通钱包
     *
     * @param saasTaskBurialPointDTO
     */
    @SneakyThrows
    public void openWalletForTheFirstTime(SaasTaskBurialPointDTO saasTaskBurialPointDTO) {
        Thread.sleep(1000);
        log.info("进入首次开通钱包消费,消费参数:{}", JSON.toJSON(saasTaskBurialPointDTO));
        // 首次开通钱包,全网只能完成一次,但是一次完成却可以完成多个任务.这个任务是直接完成的,不会进入到积攒的流程上,直接就是完成的.如果任务被完成过,那么证明他已经开户过了.
        List<SaasUserTask> byTaskTypeAndUserId = saasUserTaskDao.getByTaskTypeAndUserId(saasTaskBurialPointDTO.getTaskType(), saasTaskBurialPointDTO.getUserId());
        if (CollUtil.isNotEmpty(byTaskTypeAndUserId)) {
            log.info("该用户已经开通过钱包,不需要做任何操作,参数:{}", JSON.toJSON(saasTaskBurialPointDTO));
            return;
        }
        // 根据任务获取正在进行中且未完成的首次开通钱包任务,查询是否存在.
        List<SaasTask> meetTheTask = saasTaskDao.getByTaskTypeAndValid(saasTaskBurialPointDTO.getTaskType(), saasTaskBurialPointDTO.getUserId());
        // 没有任务,则不需要做任何操作.
        if (CollUtil.isEmpty(meetTheTask)) {
            log.info("没有任务,则不需要做任何操作,参数:{}", JSON.toJSON(saasTaskBurialPointDTO));
            return;
        }
        // 通过Java8表达式获取meetTheTask中的daoId转换为一个新的集合
//        List<Long> daoIds = meetTheTask.stream().map(SaasTask::getDaoId).collect(Collectors.toList());
//        List<UserCreatorInfo> userCreatorInfoss = userCreatorInfoDao.getDaoIds(daoIds);
//        // 获取userCreatorInfoss中的userId集合
//        List<Long> userIds = userCreatorInfoss.stream().map(UserCreatorInfo::getUserId).collect(Collectors.toList());
//        // 通过这个userIds对用户的层级关联表进行查询,获取到lv字段,然后进行升序排序,获取第一个
//        List<UserRelevance> userLevelRelations = userRelevanceDao.getByUserIdsAndRelevance(userIds, saasTaskBurialPointDTO.getUserId());
//        if (CollUtil.isEmpty(userLevelRelations)) {
//            return;
//        }

//        List<SaasTask> realTask=new ArrayList<>();
//        // 这个用户就是他最近的可完成任务的dao
//        for (UserRelevance userLevelRelation : userLevelRelations) {
//            // 通过userRelevance的userId获取userCreatorInfoss匹配的数据
//            List<UserCreatorInfo> collect = userCreatorInfoss.stream().filter(userCreatorInfo -> userCreatorInfo.getUserId().equals(userLevelRelation.getUserId())).collect(Collectors.toList());
//            if (CollUtil.isEmpty(collect)) {
//                continue;
//            }
//            // 获取到对应的dao,通过这个dao获取到指定的任务
//            UserCreatorInfo userCreatorInfo = collect.get(0);
//            // 获取真实最近的应该完成的认证任务
//            List<SaasTask> saasTasks = meetTheTask.stream().filter(saasTask -> userCreatorInfo.getId().equals(saasTask.getDaoId())).collect(Collectors.toList());
//            if (CollUtil.isNotEmpty(saasTasks)) {
//                realTask.addAll(0,saasTasks);
//                break;
//            }
//        }
//        // 清空原有的任务
//        meetTheTask.clear();
//        // 赋值新的任务,里面只会有一个才是对的
//        meetTheTask.addAll(realTask);

        // 查询用户目前是否是首次开通钱包.这里需要查询三个.连连 汇付 杉德
        // 钱包数量
        Integer walletSum = 0;
        // 杉德
        UserInfo userInfo = userInfoDao.getById(saasTaskBurialPointDTO.getUserId());
        if (BeanUtil.isNotEmpty(userInfo)) {
            if (userInfo.getSandAccountOpen()) {
                walletSum = walletSum + 1;
            }
        }

        // 汇付
//        UserHfExt userHfExt = userHfExtDao.findByUserId(saasTaskBurialPointDTO.getUserId());
//        if (BeanUtil.isNotEmpty(userHfExt)) {
//            if (userHfExt.getStatus().equals(AccountStatusEnum.SUCCESS)) {
//                walletSum = walletSum + 1;
//            }
//        }

        // 连连
        LlUserExt llUserExt = llUserExtDao.getByUserId(saasTaskBurialPointDTO.getUserId());
        if (BeanUtil.isNotEmpty(llUserExt)) {
            if (llUserExt.getStatus().equals(AccountStatusEnum.SUCCESS)) {
                walletSum = walletSum + 1;
            }
        }

        UserHnaExt userHnaExt = userHnaExtDao.getByUserId(saasTaskBurialPointDTO.getUserId());
        if (BeanUtil.isNotEmpty(userHnaExt)) {
            if (userHnaExt.getStatus().equals(AccountStatusEnum.SUCCESS)) {
                walletSum = walletSum + 1;
            }
        }
        // 记录开通数据,如果只有1的话,就是首次开通钱包.在考虑事务提交的场景下.他有可能会出现0的问题,查询不到 因为事务没提交,这个时候也给他算.
        if (walletSum > 1) {
            log.info("该用户已经开通过钱包,不需要做任何操作,参数:{}", JSON.toJSON(saasTaskBurialPointDTO));
            return;
        }
        // 如果是dao的任务,那么需要验证该用户是否在dao内.
        List<SaasUserTask> list = new ArrayList<>();
        meetTheTask.forEach(saasTask -> {
            // 任务消费的时候进行加锁,锁住一条任务,依次消费,需要防止的内容是阶段性的任务获取数量不对导致异常,也要排除掉并发的场景,所以在这里用锁对他进行控制
            if (saasTask.getTaskVisible().equals(SaasTaskVisibleEnum.DAO)) {
                // 如果这个任务是某个dao的任务的话,那么需要验证这个用户是否在这个dao的网体下.不是直接结束.
                if (!sublink(saasTask, saasTaskBurialPointDTO.getUserId())) {
                    return;
                }
            }
            // 任务可完成数量-1  如果任务可完成数量为0,那么就是不可完成的任务. 就不需要落库了.
            if (!saasTaskDao.taskSubtract(saasTask.getId(), 1)) {
                return;
            }

            // 任务完成上限
            if (taskUpperLimit(saasTask, saasTaskBurialPointDTO.getUserId())) {
                return;
            }
            SaasUserTask saasUserTask = new SaasUserTask();
            saasUserTask.setSaasTaskId(saasTask.getId());
            saasUserTask.setAccomplishSum(1);
            saasUserTask.setTaskTrace(saasTask.getTaskTrace());
            saasUserTask.setUserId(saasTaskBurialPointDTO.getUserId());
            saasUserTask.setTaskType(saasTaskBurialPointDTO.getTaskType());
            saasUserTask.setSchedule(BigDecimal.ONE);
            saasUserTask.setVoluntarySum(0);
            saasUserTask.setStatus(Boolean.FALSE);
            // 需要根据任务的配置,给用户发放奖励.
            TaskAwardIdAndStageIdVO taskAwardIdAndStageId = getTaskAwardIdAndStageId(saasTask, saasTaskBurialPointDTO.getUserId());
            saasUserTask.setTaskAwardId(taskAwardIdAndStageId.getAwardId());
            saasUserTask.setStageId(taskAwardIdAndStageId.getStageId());
            saasUserTask.setSaasType(saasTask.getSaasType());
            saasUserTask.setFulfilStatus(Boolean.TRUE);
            saasUserTask.setFulfilTime(DateUtil.date());
            saasUserTask.setOverTime(saasTask.getTaskEnd());
            saasUserTask.setSaasType(saasTask.getSaasType());
            list.add(saasUserTask);
        });
        log.info("数据落库.请求参数:{},落库参数:{}", JSON.toJSON(list), JSON.toJSON(saasTaskBurialPointDTO));
        // 数据落库
        saasUserTaskDao.saveBatch(list);
        addSaasTaskDrawPrize(list);
    }

    /**
     * 根据任务的id获取奖励的id
     *
     * @param saasTask
     * @param userId
     * @return
     */
    @SneakyThrows
    public TaskAwardIdAndStageIdVO getTaskAwardIdAndStageId(SaasTask saasTask, Long userId) {
        TaskAwardIdAndStageIdVO taskAwardIdAndStageIdVO = new TaskAwardIdAndStageIdVO();
        // 阶段id
        Long stageId = null;
        SaasTaskStageConditions saasTaskStageConditions = saasTaskStageConditionsDao.getByTaskIdStageConfig(saasTask.getId());
        taskAwardIdAndStageIdVO.setStageId(saasTaskStageConditions.getId());
        if (BeanUtil.isNotEmpty(saasTaskStageConditions)) {
            stageId = saasTaskStageConditions.getId();
            // 把这条库存结果-1
            Boolean minusInventory = saasTaskStageConditionsDao.minusInventory(saasTaskStageConditions.getId(), 1);
            if (!minusInventory) {
                // 如果报了错误,那么就开始重新投递进行消费.达到一定次数他会进入死信队列.
                throw new GlobalRunTimeException("任务阶段库存不足");
            }
        } else {
            return taskAwardIdAndStageIdVO;
        }

        // 获取阶段id
        // 根据saasTask的id获取奖励的数据,在根据用户id获取这些奖励里面的获取所需要持有的藏品,根据藏品的持有优先级,获取权重最大的那个.
        // 5.6.0需求改版,在前面最新套了一层.这一层的作用是拿来在最外层套了一层,获取当前最新的范围,让后获取到的数据给他根据范围获取到的数据进行比对.
        List<SaasTaskAward> saasTaskAwards = saasTaskAwardDao.getByTaskIdAndStageId(saasTask.getId(), stageId);
        // 藏品集合id.查询用持有哪些的id藏品
        List<Long> collectionIds = saasTaskAwards.stream().map(SaasTaskAward::getCollectionId).collect(Collectors.toList());
        // 获取用户持有的奖励的藏品
        List<UserCollection> byCollectionIdAndUserId = userCollectionDao.getByCollectionIdAndUserId(collectionIds, userId);
        // 获取奖励的藏品持有的id
        List<Long> userCollectionIds = byCollectionIdAndUserId.stream().map(UserCollection::getCollectionId).collect(Collectors.toList());
        if (CollUtil.isEmpty(userCollectionIds)) {
            // 理论上奖励不会为空,以防万一做一个空判定防止报错回滚用户写不进去数据导致事务回滚.
            if (CollUtil.isEmpty(saasTaskAwards)) {
                return taskAwardIdAndStageIdVO;
            }
            // 如果所有的藏品用户都没有持有的话,那么给saasTaskAwards中weight字段最小的那个.
            SaasTaskAward saasTaskAward = saasTaskAwards.stream().min(Comparator.comparing(SaasTaskAward::getWeight)).get();
            // 如果这个最小权重的奖励也是必须持藏品的话,那么就也给空
            if (saasTaskAward.getCollectionId() != null) {
                return taskAwardIdAndStageIdVO;
            }
            taskAwardIdAndStageIdVO.setAwardId(saasTaskAward.getId());
            return taskAwardIdAndStageIdVO;
        } else {
            // 如果有,就比对collectionSimplenessByIds中的id和saasTaskAwards中的id,如果相同,那么就是这个藏品,如果不相同,那么就是weight最小的那个.
            // 把saasTaskAwards根据权重weight进行从大到小进行排序
            List<SaasTaskAward> collect = saasTaskAwards.stream().sorted(Comparator.comparing(SaasTaskAward::getWeight).reversed()).collect(Collectors.toList());
            // 循环比对collect和collectionSimplenessByIds,哪个存在,就返回哪个,全都没有 给最小
            for (SaasTaskAward saasTaskAward : collect) {
                if (userCollectionIds.contains(saasTaskAward.getCollectionId())) {
                    taskAwardIdAndStageIdVO.setAwardId(saasTaskAward.getId());
                    return taskAwardIdAndStageIdVO;
                }
            }
        }
        return taskAwardIdAndStageIdVO;
    }

    /**
     * 验证这个用户,是否在某个dao持有者的网体下
     *
     * @param saasTask
     * @param userId
     * @return
     */
    public Boolean sublink(SaasTask saasTask, Long userId) {
        // 这里修改为参与人为DAO下，才可以匹配
        if (saasTask.getTaskVisible() == SaasTaskVisibleEnum.ALL) {
            // 如果是全部的话，证明所有人都可以参与，直接返回true
            return Boolean.TRUE;
        }
        UserCreatorInfo userCreatorInfo = userCreatorInfoDao.getById(saasTask.getDaoId());
        if (BeanUtil.isEmpty(userCreatorInfo)) {
            return Boolean.FALSE;
        }
        // 查询这个用户是否是这个dao主理人网体下的用户
        if (userId.equals(userCreatorInfo.getUserId())) {
            // 自己也可以参加
            return Boolean.TRUE;
        }
        UserRelevance subordinate = userRelevanceDao.subordinate(userCreatorInfo.getUserId(), userId);
        // 这个标识位是用来判定是否需要查询dao的任务
        Boolean dao = Boolean.FALSE;
        if (BeanUtil.isNotEmpty(subordinate)) {
            dao = Boolean.TRUE;
        }
        return dao;
    }


    /**
     * 验证用户任务上限
     *
     * @param saasTask
     * @param userId
     * @return
     */
    public Boolean taskUpperLimit(SaasTask saasTask, Long userId) {
        Integer taskEveryoneSum = saasTask.getTaskEveryoneSum();
        Integer countByTaskId = saasUserTaskDao.countByTaskId(saasTask.getId(), userId);
        if (taskEveryoneSum <= countByTaskId) {
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }


    public Integer accomplishSum(SaasTask saasTask, Long userId) {
        Integer countByTaskId = saasUserTaskDao.countByTaskId(saasTask.getId(), userId);
        if (countByTaskId == null) {
            return 1;
        }
        return countByTaskId + 1;
    }



    private Integer countOrders(SaasTaskBurialPointDTO taskBurialPointDTO) {
        Integer totalCount = 0;
        //查询首发订单是否存在
        Integer orderCount = orderService.orderCount(taskBurialPointDTO.getUserId());
        //查询二级市场订单
        Integer secondOrderCount = secondOrderService.countOrder(taskBurialPointDTO.getUserId());
        //查下原石订单
        Integer countRoughStoneOrder = roughStoneOrderService.countRoughStoneOrder(taskBurialPointDTO.getUserId());
        //权益道具订单
        Integer equityCount = equityPropsOrderService.countOrder(taskBurialPointDTO.getUserId());

        //总数
        totalCount = orderCount + secondOrderCount + countRoughStoneOrder + equityCount;

        return totalCount;
    }
}
